Coffeescript 按索引删除数组值

Posted

技术标签:

【中文标题】Coffeescript 按索引删除数组值【英文标题】:Coffeescript remove array value by index 【发布时间】:2014-05-04 17:46:54 【问题描述】:

我有一个对象数组,我想通过它的索引删除一个值。我有一个方法,将要删除的值传递给该方法,该方法找到传递的参数值:

remove: (val) ->
  for el, index in @arr
    if el is val
      # remove el from @arr...

CoffeeScript website 很清楚地说,为了替换我想要的元素,我必须做@arr[index] = 'something',但没有说要完全删除它。

【问题讨论】:

【参考方案1】:

只需使用.splice():

for index, elem in @arr
    @arr.splice index, 1 if elem is val

如果您不关心 Internet Explorer 7 或 8,您可以进一步简化它:

@arr.splice @arr.indexOf(val), 1

这假定该元素存在于数组中,否则它将删除最后一个元素。如果您需要检查它是否存在,您可以使用一个小技巧:

@arr.splice (@arr.indexOf(val)+1 or @arr.length+1)-1, 1

与“仅咖啡”过滤器解决方案相比,您可以获得 4-8 倍的性能(在 Chrome 中):

从包含 10.000.000 个整数的数组中移除 5 个随机元素

每个移除元素后的累积执行时间

过滤方法

197 毫秒 422ms 626 毫秒 847ms 1087ms

拼接方法

33 毫秒 83 毫秒 142 毫秒 198 毫秒 255ms

拼接和indexOf方法

27 毫秒 70ms 88ms 116 毫秒 134 毫秒

测试代码 - 又快又脏(不考虑随机选择两次相同的值):

log "coffee method"
arr = [0..9999999]
length = arr.length
start = new Date().getTime()
for num in [1..5]
    val = Math.round(Math.random() * length)
    do (val) -> arr = (x for x in arr when x isnt val)
    log new Date().getTime()-start+"ms"

log "splice method"
arr = [0..9999999]
length = arr.length
start = new Date().getTime()
for num in [1..5]
    val = Math.round(Math.random() * length)
    for index, elem in arr
        arr.splice index, 1 if elem is val
    log new Date().getTime()-start+"ms"

log "splice method with indexOf()"
arr = [0..9999999]
length = arr.length
start = new Date().getTime()
for num in [1..5]
    val = Math.round(Math.random() * length)
    arr.splice arr.indexOf(val), 1
    log new Date().getTime()-start+"ms"

演示:http://jsfiddle.net/j9CZz/1/

【讨论】:

目前,我使用.splice。这就是 javascript 的方式。我只是想要更多的 CoffeeScript 方法。 但是coffeescript使用Javascript...?无论你在咖啡中做什么,最终都会使用 JS,因此最好的性能和最自然的事情就是使用原生 JS 解决方案。 你能从 javascript 数组中删除一个元素,同时还对其进行迭代吗? 当然它使用 JavaScript ......我的意思是我是否可以使用 CoffeeScript 提供的一些好处(如果在这种情况下有这样的话)。在这种情况下,过滤器或多或少地适合......我是要使用它们还是坚持自然的 JS 方式,仍然没有决定。 @Cupcake 是的,这将在删除匹配元素的同时继续迭代数组的其余部分【参考方案2】:

文档给出了一个使用过滤器的例子,所以也许你可以尝试一下?:

remove: (val) -> @arr = (x for x in @arr when x isnt val)

【讨论】:

这不仅会创建整个数组的第二个内存副本(减去 1 个元素),而且还会遍历所有元素,而不是只遍历必须删除的元素。另外,它需要 3 倍的代码,创建 4 个新变量和一个匿名函数。

以上是关于Coffeescript 按索引删除数组值的主要内容,如果未能解决你的问题,请参考以下文章

Coffeescript / Node.js:如何从对象数组中删除重复对象?

从 javascript 数组中删除元素的干净方法(使用 jQuery、coffeescript)

firebase 按索引从字段数组中删除对象

在 CoffeeScript 中,如何将值附加到数组?

从数组中按索引删除项目的更短方法[重复]

python 数组中如何根据值,获取索引,如何根据索引删除值 , 以及如何根据值删除值