【问题标题】:Coffeescript remove array value by indexCoffeescript 按索引删除数组值
【发布时间】: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',但没有说要完全删除它。

【问题讨论】:

    标签: javascript arrays coffeescript


    【解决方案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 个新变量和一个匿名函数。
    猜你喜欢
    • 2012-04-22
    • 2015-09-24
    • 2012-10-25
    • 1970-01-01
    • 1970-01-01
    • 2016-03-25
    • 2016-05-20
    • 1970-01-01
    • 2015-01-23
    相关资源
    最近更新 更多