【问题标题】:Functional programming in Scala: find index of an element in a multidimensional listScala中的函数式编程:在多维列表中查找元素的索引
【发布时间】:2021-06-17 06:15:14
【问题描述】:

我有一个二维列表ll : List[List[T]] 和一个函数f : T => Boolean。我想找到一个整数元组(i, j),这样f(l(i)(j)) == true 只要它存在,就可能包裹在Option 中,并且想以函数式编程的方式来做这件事。我目前的工作解决方案如下:

ll.zipWithIndex
  .flatMap{case (l, i) => l.map((_, i)).zipWithIndex}
  .find{case ((l, _), j) => f(l(j))}
  .map{case ((_, i), j) => (i, j)}

但是,我觉得应该有更好的方法来实现这一点 - 我的解决方案非常麻烦,并且不能很好地推广到高维数组。那么有没有更好的方法来做到这一点?

在我走之前:我完全知道这很容易通过嵌套的 for 循环实现。所以我只对函数式编程风格的解决方案感兴趣。

【问题讨论】:

  • for 理解只是 map()flatMap() 调用的语法糖。那有什么非 FP 呢?

标签: arrays scala multidimensional-array indexing find


【解决方案1】:
(for { 
  (l, i) <- ll.zipWithIndex
  (e, j) <- l.zipWithIndex
  if f(e)
} yield (i, j)).headOption

【讨论】:

    【解决方案2】:

    您没有提供任何用于测试的示例输入,但这似乎可行。它返回一个IndexedSeq[(Int, Int)] 集合,应该(我认为)包含所有(i,j) 对,其中f(ll(i)(j)) 返回true

    ll.indices
      .flatMap(i => ll(i).indices
                         .collect{case j if f(ll(i)(j)) => (i,j)})
    

    和这个差不多……

    for {
      i <- ll.indices
      j <- ll(i).indices
      if f(ll(i)(j))
    } yield (i,j)
    

    ...并且,如 cmets 中所述,完全兼容 FP。

    【讨论】:

    • 只有一个注释,通过索引访问 List 非常慢,最好使用 zipWithIndex 并且也许还使用 Iterators 来做一次迭代中的所有内容。
    • 呃...这比甚至二次还要糟糕:/
    猜你喜欢
    • 2013-07-26
    • 1970-01-01
    • 2011-02-05
    • 1970-01-01
    • 2021-06-25
    • 2013-11-21
    • 2017-04-27
    • 2010-12-02
    • 2012-01-15
    相关资源
    最近更新 更多