【问题标题】:Removing all elements of a column in a two-dimensional array删除二维数组中列的所有元素
【发布时间】:2013-05-16 16:35:16
【问题描述】:

我有这个数组:

arr = [["a","b","c"],[2,3,5],[3,6,8],[1,3,1]]

表示一个包含“a”、“b”和“c”列的虾表。

如何删除整个“c”列及其所有值 5、8、1?

也许“Create two-dimensional arrays and access sub-arrays in Ruby”和“difficulty modifying two dimensional ruby array”中有有用的提示,但我无法将它们转移到我的问题中。

【问题讨论】:

    标签: ruby arrays multidimensional-array


    【解决方案1】:
     arr = [["a","b","c"],[2,3,5],[3,6,8],[1,3,1]]
    
     i = 2   # the index of the column you want to delete
     arr.each do |row|
       row.delete_at i
     end
    
      => [["a", "b"], [2, 3], [3, 6], [1, 3]] 
    
     class Matrix < Array
       def delete_column(i)
         arr.each do |row|
          row.delete_at i
         end
       end
     end
    

    【讨论】:

      【解决方案2】:

      因为它只是您可以使用的最后一个值Array#pop

      arr.each do |a|
        a.pop
      end
      

      或者找到"c"的索引并删除该索引处的所有元素:

      c_index = arr[0].index "c"
      arr.each do |a|
        a.delete_at c_index
      end
      

      或者使用map:

      c_index = arr[0].index "c"
      arr.map{|a| a.delete_at c_index }
      

      【讨论】:

        【解决方案3】:
        arr.map { |row| row.delete_at(2) } 
        #=> ["c", 5, 8, 1]
        

        如果你真的想删除最后一列,那么它就不再在原始数组中了。如果您只想在保持arr 不变的情况下退回它:

        arr.map { |row| row[2] }
        #=> ["c", 5, 8, 1]
        

        如果要删除与特定标题对应的列中的所有元素:

        if index = arr.index('c') then
           arr.map { |row| row[index] }  # or arr.map { |row| row.delete_at(index) }
        end
        

        【讨论】:

        • 需要if index = arr[0].index('c')
        【解决方案4】:

        假设数组的第一个元素总是一个列名数组,那么你可以这样做:

        def delete_column(col, array)
          index = array.first.index(col)
          return unless index
          array.each{ |a| a.delete_at(index) }
        end
        

        它将修改传入的数组。你不应该将它的输出分配给任何东西。

        【讨论】:

          【解决方案5】:

          出于好奇,这里是另一种方法(单线):

          arr.transpose[0..-2].transpose
          

          【讨论】:

          • 或只是 arr.transpose[2] 以返回该列。
          • @MarkReed 我宁愿建议 arr.transpose.lastarr.transpose[-1] 作为更通用的解决方案。
          • @MarkReed 我们有Array#pop,正如我发布的那样,它会很好地完成这项工作。 :)
          【解决方案6】:
          # Assuming first row are headers
          arr = [["a","b","c"],[2,3,5],[3,6,8],[1,3,1]]
          
          col = arr.first.index "c"
          arr.each { |a| a.delete_at(col) }
          

          【讨论】:

            【解决方案7】:
            arr = [["a","b","c"],[2,3,5],[3,6,8],[1,3,1]]
            arr.map(&:pop)
            p arr #=> [["a", "b"], [2, 3], [3, 6], [1, 3]]
            

            【讨论】:

              【解决方案8】:

              我有一个更普遍的需要,即删除一个或多个与文本模式匹配的列s(不仅仅是删除最后一列)。

               col_to_delete = 'b'
               arr = [["a","b","c"],[2,3,5],[3,6,8],[1,3,1]]
               arr.transpose.collect{|a| a if (a[0] != col_to_delete)}.reject(&:nil?).transpose
               => [["a", "c"], [2, 5], [3, 8], [1, 1]] 
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2022-01-25
                • 2021-06-14
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2016-07-13
                相关资源
                最近更新 更多