如何用另一个Seq元素替换Seq的第n个元素?

时间:2018-04-26 14:19:43

标签: scala

我们假设我们有以下项目清单。

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")
  )
}

Utilities的骨架类如下:

final case class Utilities(item_name: String, ref_id: Int, 
                           item_type: String, sale_status: String, status: String)

我们还有Utilities当前销售状态的另一个项目列表:(该类与Utilities没有任何关系,我们只打算将其第二列应用于实用工具。)

val newAttr: Seq[NewAttributes] = {
      Seq(
        NewAttributes(1,  "For sale"),
        NewAttributes(3,  "Not for sale"),
        NewAttributes(18, "Discontinued")
      )
    }

NewAttributes的骨架类如下:

final case class NewAttributes(r_id: Int, status: String)

如何按顺序用Utilities sale_status 替换NewAttributes' status 记录?

使用新的更新,Utilities应如下:

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")

我使用以下代码成功检索newAttr中的元素,但我不知道如何将它们应用于utils以实现上述架构。

val prepStatuses = 
   for(na <- newAttr)
      yield na.status

非常感谢任何帮助!

4 个答案:

答案 0 :(得分:2)

如果订单是正确的,那就是直截了当:

  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)
  }

答案 1 :(得分:1)

您需要一种方法来查找所需的数据:

def findStatus(id: Int): Option[String] = 
  newAttr.find(_.r_id == id).map(_.status)

然后你需要在理解中使用它:

val mappedUtils = for(u <- utils)
  yield u.copy(sale_status = findStatus(u.ref_id).getOrElse(sys.error(s"No such id ${u.ref_id}")))

答案 2 :(得分:0)

您可以使用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)

说明:
zipWithIndex生成一个Tuple2,其中第一个值是原始值,第二个值是每个值的索引。例如newAttr.zipWithIndex将产生

  (NewAttributes(1, "For sale"),1)
  (NewAttributes(3, "Not for sale"),2)
  (NewAttributes(18, "Discontinued"),3)

_.swap交换上面生成的tuple2值,.toMap为每个Tuple2记录生成地图,因此zippedNewAttr

  (1 -> NewAttributes(1, "For sale"))
  (2 -> NewAttributes(3, "Not for sale"))
  (3 -> NewAttributes(18, "Discontinued"))

for循环再次生成Utilities对象,但包含已替换的Utilities sale_status记录,其中包含NewAttributes status zipWithIndex保留订单

<强>更新

使用迭代器还有另一种更好的方法

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是必需的输出

答案 3 :(得分:0)

您可以使用修改后的sale_status将每个index的utils映射到相应utils元素的copy

utils.indices.map(i => utils(i).copy(sale_status = newAttr(i).status))