使用原始的非过滤元素过滤功能语言?

时间:2011-10-04 18:40:21

标签: javascript arrays list scala functional-programming

我想返回一个映射一些过滤元素的数组 - 但我希望将未过滤的元素保留在原来的位置。 即,有一个简单的方法吗?:

array
.filter(
  function(element){
    // some test
  }
)
.map(
  function(element){
    // some mapping
  }
)

我提出的最接近的解决方案是:

array
.map(
  function(value, index){
    if (<test>) {
      return <mapping>(value);
    }
  }
)

但我觉得这有点打破了函数式编程的精神。

我不是要求特定的语言实现,尽管Scala或JavaScript中的示例会很好。

编辑:这是我正在寻找的具体例子:

[1,2,3,4,11,12]

将所有元素映射到元素* 10,对于数组中大于10的所有元素,应该产生

[1,2,3,4,110,120]

EDIT2:我为使用“mutate”这个词道歉。我并不是要改变原始数组 - 我正在考虑改变数组的副本。

7 个答案:

答案 0 :(得分:3)

如果您使用的是可变集合,那么它并不会真正起作用。但您可以在Scala中使用transform

scala> val a = Array(1,2,3,4,11,12)
a: Array[Int] = Array(1, 2, 3, 4, 11, 12)

scala> a.transform {i => if(i > 10) i * 10 else i}
res10: scala.collection.mutable.WrappedArray[Int] = WrappedArray(1, 2, 3, 4, 110, 120)

修改 如果您希望过滤器和地图分开,请使用view

scala> a
res22: Array[Int] = Array(1, 2, 3, 4, 11, 12)

scala> a.view.filter(_ > 10).transform(_ * 10)
res23: scala.collection.mutable.IndexedSeqView[Int,Array[Int]] = SeqViewF(...)

scala> a
res24: Array[Int] = Array(1, 2, 3, 4, 110, 120)

答案 1 :(得分:2)

collect你的目标是什么?

scala> List(2, 3, 5, 6, 9).filter(_ < 5).map(_ * 100)
res30: List[Int] = List(200, 300)

scala> List(2, 3, 5, 6, 9).collect { case i if i < 5 => i * 100 }
res31: List[Int] = List(200, 300)

答案 2 :(得分:2)

您可以将过滤器和地图功能提供给“组合”功能;我在http://jsfiddle.net/xtofl/UDbyL/上尝试过一个例子。

我们的想法是将'mapping'(我称之为 inplace mapping )应用于符合原始数组中的过滤谓词的所有元素。

答案 3 :(得分:2)

虽然原则上可以进行这些操作,但Scala库不提供它们。

您可以使用索引(或索引视图)构建自己的:

scala> val a = Array(1,2,3,4,5)
a: Array[Int] = Array(1, 2, 3, 4, 5)

scala> a.indices.view.filter(i=>a(i)%2==0).foreach(i=>a(i)=0)

scala> a
res1: Array[Int] = Array(1, 0, 3, 0, 5)

这有点尴尬,但通常比if语句版本好一点(至少你可以分别看到过滤器和分配步骤。)

答案 4 :(得分:1)

Hej jiaweihli

最简单的解决方案是将其重新分配给参考...即改变参考 而不是数据。如果引用在其他地方,这有一些好处 并没有在那些鼻子下改变它。

EX:

x = x.filter(filterOpp);

PS!第二个例子有剂量。 GL

答案 5 :(得分:1)

您遇到的问题是您正在考虑过滤,而过滤不是您想要的。如果您不想删除元素,则它不是过滤器。

您只需要一张简单的地图:

array.map(x => if(x > 10) x * 10 else x)

或者,如果您认为自己的情况过于复杂,

array.map {
    case x if x > 10 => x * 10
    case x => x
}

答案 6 :(得分:0)

这样的事情:(psuedo javascript)

  filteredMap = function(element) {
    if(filterFunc(element)){
      return mapFunc(element);
    }
    return element;
  }


  array = array.map(filteredMap)

除非你明确要求改变数组(这不是“功能”),否则这应该可以得到你想要的东西。