【问题标题】:How to drop the end of an array in Ruby如何在Ruby中删除数组的末尾
【发布时间】:2012-11-12 01:27:52
【问题描述】:

Array#drop 删除数组的前 n 个元素。删除数组的最后一个 m 元素的好方法是什么?或者,保留数组中间元素(大于n,小于m)的好方法是什么?

【问题讨论】:

  • 因为您可以在 ruby​​ 中使用范围索引数组,所以将中间元素分配给一个新数组并使用它可能会很方便。 foo = [1,2,3,4,5,6,7,8] => [1, 2, 3, 4, 5, 6, 7, 8] bar = foo[2..4] => [ 3、4、5]

标签: ruby arrays iterator


【解决方案1】:

Array#delete_at() 是删除数组最后一个元素的最简单方法,因此

arr = [1,2,3,4,5,6]
arr.delete_at(-1) # => [1,2,3,4,5]

要删除数组的一个或多个段,请使用其他答案中的方法。

【讨论】:

    【解决方案2】:

    我希望返回值是没有删除元素的数组。我在这里找到了几个解决方案:

    count = 2
    [1, 2, 3, 4, 5].slice 0..-(count + 1) # => [1, 2, 3]
    [1, 2, 3, 4, 5].tap { |a| a.pop count } # => [1, 2, 3]
    

    但如果数组的顺序不重要(在我的情况下我正在删除文件),我发现另一种更具可读性的解决方案:

    count = 2
    [1, 2, 3, 4, 5].reverse.drop count # => [3, 2, 1]
    

    如果您需要保持秩序,您可以在此处添加另一个 .reverse,但我认为我更喜欢 tap 解决方案。

    【讨论】:

      【解决方案3】:

      您可以以非破坏性的方式实现与Array#pop 相同的效果,并且无需知道数组的长度:

      a = [1, 2, 3, 4, 5, 6]
      b = a[0..-2]
      # => [1, 2, 3, 4, 5]
      n = 3 # if we want drop the last n elements
      c = a[0..-(n+1)]
      # => [1, 2, 3]
      

      【讨论】:

        【解决方案4】:

        你也可以添加一些方法

        class Array
        
          # Using slice
          def cut(n)
            slice(0..-n-1)
          end
        
          # Using pop
          def cut2(n)
            dup.tap{|x| x.pop(n)}
          end
        
          # Using take
          def cut3(n)
            length - n >=0 ? take(length - n) : []
          end
        
        end
        
        [1,2,3,4,5].cut(2)
         => [1, 2, 3] 
        

        【讨论】:

        • 正如我在这里看到的ruby-doc.org/core-1.9.3/Array.html#method-i-pop 太棒了!方法并返回弹出的元素而不是结果数组,您应该使用 dup 或在对象的 tne tap 中使用,如 ary.tap{|x| x.drop(2)}
        • 其实你的方法对应last(n)。另请注意,您的方法中不需要length
        • #last 返回 self 的最后一个元素。如果数组为空,则第一种形式返回 nil。我的方法通过 n 返回带有剪尾的 self
        • @Marc-AndréLafortune 也与 my_array.dup.tap{|x| 相同x.pop(n)}
        • 猴子补丁原生代码通常是不好的做法。
        【解决方案5】:

        这正是Array#pop 的用途:

        x = [1,2,3]
        x.pop(2) # => [2,3]
        x # => [1]
        

        【讨论】:

        • @ggPeti:我知道这一点。问题的标题似乎暗示OP确实想要更改原始数组。
        • 考虑到 OP 要求 remove 最后 m 个元素,这是正确的答案。 Pop 将它们从原始数组中移除,而 drop 或 slice 创建一个新数组。
        【解决方案6】:

        这将去掉最后 n 个元素:

        a = [1,2,3,4,5,6]
        n = 4
        p a[0, (a.size-n)]
        
        #=> [1, 2]
        
        n = 2
        p a[0, (a.size-n)]
        #=> [1, 2, 3, 4]    
        

        关于“中间”元素:

        min, max = 2, 5
        p a.select {|v| (min..max).include? v }
        #=> [2, 3, 4, 5]
        

        【讨论】:

          【解决方案7】:

          drop(删除前n 个元素)最直接相反的是take,它保留前n 个元素(还有take_while,类似于drop_while)。

          Slice 允许您通过指定范围或偏移量和长度来返回数组的子集。当传递一个范围作为参数或传递 2 个数字时,Array#[] 的行为相同

          【讨论】:

            【解决方案8】:

            你也可以使用 Array#slice 方法,例如:

            [1,2,3,4,5,6].slice(1..4) # => [2, 3, 4, 5]
            

            a = [1,2,3,4,5,6]
            a.take 3 # => [1, 2, 3]
            a.first 3 # => [1, 2, 3]
            a.first a.size - 1 # to get rid of the last one
            

            【讨论】:

            • 还有Array#slice!,当需要就地修改数组时。
            • Array#slice! 似乎与Array#slice 没有什么不同。
            猜你喜欢
            • 2012-12-27
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-06-14
            • 1970-01-01
            相关资源
            最近更新 更多