如何在Scala中正确映射?

时间:2017-09-04 14:11:41

标签: scala list loops

我有一个这个对象的列表:

case class Alloc(
                         segId: String,
                         paxId: String,
                         cos: String,
                         fare: String,
                         type: String,
                         promo: Boolean,
                         cosLev: String)

,我目前有一个10的列表,所有属性都有一个值,除了paxId,所有对象都有“”。 现在我想增加每个paxId,我的意思是第一个Alloc有paxId = 1,第二个有2个,第十个有10个。 我试过这个:

val allocWithPaxIds: List[Allocation] = for (id <- 1 to 10) {
        allocs.map(alloc=>Alloc.apply(alloc.segId, id, alloc.cos, alloc.fare, alloc.type, false, alloc.cosLev))
    }

包含不带paxIds的alloc的allocs

我是斯卡拉的初学者,我很迷茫,希望你能帮助我。

提前致谢

2 个答案:

答案 0 :(得分:2)

您可以使用zipWithIndex,然后使用copy仅修改每个对象的一个​​字段

list.zipWithIndex.map{
   case (v, idx) => v.copy(paxId = idx.toString)
}

答案 1 :(得分:0)

所以,只是为了澄清你的实施发生了什么。

首先,您可能需要了解理解的工作原理。

https://docs.scala-lang.org/tutorials/FAQ/yield.html

  斯卡拉的“用于理解”是用于构成的语法糖   使用foreach,map,flatMap,filter或withFilter进行多次操作。

而且您的代码没有folium.RegularPolygonMarker(location=(32.900908, -97.040335), fill_color='blue', number_of_sides=3, radius=10, rotation=???).add_to(m) 任何内容的事实将被转换为// localImage would be the cropped image of the square you have drawn, // the global image is the original image and phoneSquare is the Rect you // have drawn localImage = new Mat(globalImage, phoneSqure).clone(); // make the phone black and surroundings white Imgproc.threshold(localImage, localImage, 127, 255, Imgproc.THRESH_OTSU + Imgproc.THRESH_BINARY_INV); // get contours ArrayList<MatOfPoint> contours = new ArrayList<>(); Mat hierarchy = new Mat(); Imgproc.findContours(canny, contours, hierarchy, Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_NONE); // sort contours by size and get the biggest which is assumed to be the outer contour of the phone contours.sort(new Comparator<MatOfPoint>() { @Override public int compare(MatOfPoint o1, MatOfPoint o2) { return (int) Math.signum(o2.size().area() - o1.size().area()); } }); MatOfPoints biggestContour = contours.get(contours.size() - 1); // get the bounding rectangle of the phone, the you can get the width Rect whatYouWant = Imgproc.boundingRect(biggestContour); 方法,其返回类型为yield,这意味着您永远不会从中获取列表。

我会尝试逐步修改您的代码。

forEach

您无需明确调用Unitfor (id <- 1 to 10) { allocs.map(alloc => Alloc.apply(alloc.segId, id, alloc.cos, alloc.fare, alloc.type, false, alloc.cosLev)) } 方法只是一种语法糖,如果你实现它,你可以像函数一样使用它。在这种情况下,apply为您完成了这项工作。

(有关此主题的更多信息,请访问:https://twitter.github.io/scala_school/basics2.html#apply

apply

此处您不需要理解,因为要更新的内容只有case classfor (id <- 1 to 10) { allocs.map(alloc => Alloc(alloc.segId, id, alloc.cos, alloc.fare, alloc.type, false, alloc.cosLev)) } ,因此您可以使用id提供的promo }。

copy

只是

case class

你想要填充从1到10的id,这样你就可以allocs.map(alloc => alloc.copy(id = id, promo = false)) 将它们放在一起,这将返回List [(Int,Alloc)]并使用部分函数映射它来进行模式匹配并对元组进行解构

(更多关于部分功能:https://twitter.github.io/scala_school/pattern-matching-and-functional-composition.html#PartialFunction

allocs.map(_.copy(id = id, promo = false))

而且,是的,如果您愿意,可以使用zip作为Mikel建议。

我想指出的最后一件事是,我将allocs .zip(1 to 10) .map { case (alloc, id) => alloc.copy(id = id.toString, promo = false) } 视为zipWithIndex的属性,其类型为type

这可能与问题无关,但您可以更多地利用Scala类型系统的强大功能来确保程序的正确性。由于可能值越小意味着更具可预测性。所以你可以考虑使用sum类型(或联合类型)。

(更多关于总和类型:http://tpolecat.github.io/presentations/algebraic_types.html#11

相关问题