【问题标题】:Delete first instance of matching element from array从数组中删除匹配元素的第一个实例
【发布时间】:2011-06-03 11:27:43
【问题描述】:

假设我有数组[1,2,3,1,2,3],我想从数组中删除(比如说)2 的第一个实例,给出[1,3,1,2,3]。最简单的方法是什么?

【问题讨论】:

    标签: ruby arrays


    【解决方案1】:
    li.delete_at(li.index(n) || li.length)
    

    li[li.length] 超出范围,因此|| li.length 处理n 不在列表中的情况。

    irb(main):001:0> li = [1,2,3,1,2,3]
    => [1, 2, 3, 1, 2, 3]
    irb(main):002:0> li.delete_at(li.index(2) || li.length)
    => 2
    irb(main):003:0> li.delete_at(li.index(42) || li.length)
    => nil
    irb(main):004:0> li
    => [1, 3, 1, 2, 3]
    

    【讨论】:

    • 谢谢。我一直在努力尝试优雅地表达这一点。
    • 看不懂|| li.length 谁能解释一下
    • ruby 中的任何值都可以被视为布尔值,只有 false 和 nil 评估为 false。双管道语法是一种方便的简写。 a || b 的意思是“a,除非它是 nil,然后是 b”。
    • @erich2k8 所以li.length 只是另一种说法“不要删除任何东西(因为长度(n)总是超出数组,并返回'nil'?”
    • @stevec 是的,完全正确。如果在野外遇到这可能会有点令人困惑,但这是一种使其成为仅进行一次遍历的 1-liner 的方法。或者,您可以将索引存储在变量中,然后仅当变量值不是nil 时才执行delete_at。不过,这些变量在检查后有点混乱。例如。 index = arr.index(3) && arr.delete_at(index) 之后留下 index 变量。
    【解决方案2】:

    如果|| li.length 是为了避免将nil 发送到li.delete_at(这会导致TypeError),那么更易读的版本可能如下所示

    li.delete_at li.index(42) unless li.index(42).nil?

    【讨论】:

    • 您可能希望将li.index(42) 存储在一个变量中,以防止进行两次搜索。大型阵列的性能会好得多。
    【解决方案3】:

    也许它应该成为标准库的一部分:

    class Array
      def delete_first item
        delete_at(index(item) || length)
      end
    end
    

    【讨论】:

    • 强烈同意。 delete_at(index(item) || length) 当你知道它时非常容易,但在其他情况下并不明显。 delete_first 很不错。
    • 是否有地方(更正式地)为 ruby​​ 提出建议?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-31
    • 2019-01-05
    • 1970-01-01
    相关资源
    最近更新 更多