J Hubbard
J Hubbard

Reputation: 107

Scala; How can I iterate through a list and iterate through another list within each iteration

I will try to explain my question as well as I can.

So I have a list of stock items, within a delivery. I would like to be able to iterate through this list and find the matching product id by iterating through a product list until the product id of the stock items list and the product list match and then increment product quantities.

So the StockItem class looks like this:

case class StockItem(val spiId : Int, val pId :Int, val sdId :Int, val quan : Int)

And my Product class looks like this:

case class Product(val prodId : Int, val name : String, val desc : String, val price : Double, var quantity : Int, val location : String)

I have a method to find all the StockItems that have a particular spId, which returns a list of StockItems:

def findAllItemsInSP(sdId: Int): List[StockPurchaseItem] = stockPurchaseItems2.filter(_.sdId == sdId)

I have another method which is unfinished to iterate through this list and increment the quantities of each product:

    def incrementStock(spID: Int){
      val items = StockPurchaseItem.findAllItemsInSP(spID)

    for (i <- items){
      if(i.pId == products.prodId)
    }
  }

products is a set of Product objects. Obviously products.prodId doesn't work as I need to be refering to one element of the products Set, not the whole set. I don't know how to find the matching product id in the set of Products. Any help given, I would be very grateful for.

Note: sdId and spId refer to the same thing.

Many thanks Jackie

Upvotes: 0

Views: 987

Answers (4)

A Spoty Spot
A Spoty Spot

Reputation: 746

You could do it with a 'for-comprehension' Docs in a similar method to below.

val stockItems: List[StockItem] = ???
val products: List[Product] = ???
val result: List[Product] = for{
    item <- stockItems
    p <- products
    if p.prodId == item.pId
} yield { p.copy(quan = p.quan + 1) } //I expect you'd want different logic to this

Upvotes: 2

jwvh
jwvh

Reputation: 51271

1st - All parameters to a case class are automatically class values, so you don't need those val labels.

2nd - You say you "have a method to find all the StockItems that have a particular spId", but the code is filtering for _.sdId == sdId. spId? sdId? A bit confusing.

3rd - You say that "products is a set of Project objects." Did you mean Product objects? I don't see any "Project" code.

So, one thing you could do is make items a Map[Int,Int], which translates pId to quantity, but with a default of zero.

val items = StockPurchaseItem.findAllItemsInSP(spID).map(x => (x.spId, x.quantity)).toMap.withDefaultValue(0)

Now you can walk through products, incrementing every quantity by items(spId).

products.foreach(p => p.quantity += items(p.spId)) // or something like that

Upvotes: 2

Simon
Simon

Reputation: 6490

def incrementStock(spID: Int){
  val items = StockPurchaseItem.findAllItemsInSP(spID)

for (i <- items) {
  for (p <- products) {
    if(i.pId == p.prodId)
      products += p
}

Upvotes: 0

J Hubbard
J Hubbard

Reputation: 107

Ok I have managed to do what I wanted to do by creating a new Product with the existing properties with that product id and then adding to the quantity.

def incrementStock(spID: Int){
      val items = StockPurchaseItem.findAllItemsInSP(spID)

    for (i <- items){
      var currentProd: Product = Product(Product.findProduct(i.pId).get.prodId, Product.findProduct(i.pId).get.name, Product.findProduct(i.pId).get.desc, Product.findProduct(i.pId).get.price, Product.findProduct(i.pId).get.quantity, Product.findProduct(i.pId).get.location)
      currentProd.quantity += i.quan

      products -= (findProduct(i.pId).get)
      products = products + currentProd
    }

    printProductInfo()
  }

Upvotes: -1

Related Questions