Reputation: 1243
Let's assume we have the following list of items.
val utils: Seq[Utilities] = {
Seq(
Utilities("jackhammer", 24, "Industrial item", "For sale", "Available"),
Utilities("axe", 19, "Home item", "For sale", "Available"),
Utilities("pick", 39, "Garage item", "For sale", "Not Available")
)
}
The skeleton class for Utilities
is as follows:
final case class Utilities(item_name: String, ref_id: Int,
item_type: String, sale_status: String, status: String)
And we also have another list of items of the current sale status of Utilities
: (The class does not have any relation with Utilities
, we only aim to apply its 2nd column into Utilities.)
val newAttr: Seq[NewAttributes] = {
Seq(
NewAttributes(1, "For sale"),
NewAttributes(3, "Not for sale"),
NewAttributes(18, "Discontinued")
)
}
The skeleton class for NewAttributes
is as follows:
final case class NewAttributes(r_id: Int, status: String)
How can I replace Utilities
' sale_status
record with the NewAttributes
status
in order?
With the new update, Utilities
shall be like:
Utilities("jackhammer", 24, "Industrial item", "For sale", "Available")
Utilities("axe", 19, "Home item", "Not for sale", "Available")
Utilities("pick", 39, "Garage item", "Discontinued", "Not Available")
I'm successfully retrieving the elements from newAttr
with the following code, but I've no idea how to apply them to utils
to achieve the above schema.
val prepStatuses =
for(na <- newAttr)
yield na.status
Any help is greatly appreciated!
Upvotes: 0
Views: 324
Reputation: 41987
You can achieve your requirement by using zipWithIndex
val zippedNewAttr = newAttr.zipWithIndex.map(_.swap).toMap
val result = for(x <- utils.zipWithIndex; y = zippedNewAttr(x._2))yield Utilities(x._1.item_name, x._1.ref_id, x._1.item_name, y.status, x._1.status)
Explanation:
zipWithIndex generates a Tuple2 where the first value is the original value and the second value is the index of each value. for example newAttr.zipWithIndex
will produce
(NewAttributes(1, "For sale"),1)
(NewAttributes(3, "Not for sale"),2)
(NewAttributes(18, "Discontinued"),3)
_.swap
swaps the above generated tuple2 values and .toMap generates map for each Tuple2 records so zippedNewAttr
is
(1 -> NewAttributes(1, "For sale"))
(2 -> NewAttributes(3, "Not for sale"))
(3 -> NewAttributes(18, "Discontinued"))
The for loop generates Utilities
object again but with the replaced Utilities sale_status
record with the NewAttributes status
and zipWithIndex preserves the order.
Updated
There is another better approach using iterators
val utilsIterator = utils.iterator
val newAttrIterator = newAttr.iterator
val result = ArrayBuffer.empty[Utilities]
while(utilsIterator.hasNext && newAttrIterator.hasNext){
val utils = utilsIterator.next()
val newAttr = newAttrIterator.next()
result.append(Utilities(utils.item_name, utils.ref_id, utils.item_type, newAttr.status, utils.status))
}
result
is the required output
Upvotes: 0
Reputation: 22449
You can simply map each index
of utils to a copy
of the corresponding utils element with modified sale_status:
utils.indices.map(i => utils(i).copy(sale_status = newAttr(i).status))
Upvotes: 0
Reputation: 33103
You need a way to find the data you need:
def findStatus(id: Int): Option[String] =
newAttr.find(_.r_id == id).map(_.status)
And then you need to use that in a for comprehension:
val mappedUtils = for(u <- utils)
yield u.copy(sale_status = findStatus(u.ref_id).getOrElse(sys.error(s"No such id ${u.ref_id}")))
Upvotes: 1
Reputation: 623
If the order is correct it is straight forward:
final case class Utilities(item_name: String, ref_id: Int, item_type: String, sale_status: String, status: String)
val utils: Seq[Utilities] = {
Seq(
Utilities("jackhammer", 24, "Industrial item", "For sale", "Available"),
Utilities("axe", 19, "Home item", "For sale", "Available"),
Utilities("pick", 39, "Garage item", "For sale", "Not Available")
)
}
final case class NewAttributes(r_id: Int, status: String)
val newAttr: Seq[NewAttributes] = {
Seq(
NewAttributes(1, "For sale"),
NewAttributes(3, "Not for sale"),
NewAttributes(18, "Discontinued")
)
}
utils.zip(newAttr).map{ case(utility, newAttribute) =>
utility.copy(sale_status = newAttribute.status)
}
Upvotes: 2