Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 清理由零组成的阵列的阵列_Arrays_Ruby_Null_Data Cleaning - Fatal编程技术网

Arrays 清理由零组成的阵列的阵列

Arrays 清理由零组成的阵列的阵列,arrays,ruby,null,data-cleaning,Arrays,Ruby,Null,Data Cleaning,例如,我有一个数组: [[nil, nil], [1, 2], [nil, nil], [nil, nil]] 最好的清洁方法是什么?数组必须只有不包含nil的数组。清洁后,必须: [[1,2]] 比如: [[nil, nil], [1, 2], [nil, nil], [nil, nil]].each {|x| x - [nil]} 调用数组上删除nil元素的方法。但是,对于这种情况,这还不够,因为您有一个数组。此外,您还需要删除非nil数组,或nil数组。您可以通过以下方式轻

例如,我有一个数组:

[[nil, nil], [1, 2], [nil, nil], [nil, nil]] 

最好的清洁方法是什么?数组必须只有不包含nil的数组。清洁后,必须:

[[1,2]]

比如:

[[nil, nil], [1, 2], [nil, nil], [nil, nil]].each {|x| x - [nil]} 


调用数组上删除
nil
元素的方法。但是,对于这种情况,这还不够,因为您有一个数组。此外,您还需要删除非nil数组,或
nil
数组。您可以通过以下方式轻松地将两者结合起来:

[[nil,nil],[1,2],[nil,nil],[nil,nil]]拒绝{arr{arr.compact.empty}

只有当您有数字的子数组或
nil
s时,这才有效。如果您的子阵列同时包含两个,例如
[1,nil,2]
,则此解决方案将保留整个子阵列

在迭代子数组时,可以对子数组进行变异以删除
nil
,但在迭代时进行变异可以被视为一种实践。然而,实现这一点的方法是使用
compact
方法的bang版本,该方法会改变原始对象:

.reject{| arr | arr.compact!.empty?}

这将采用
[[1,2,nil,3]]
并返回
[[1,2,3]]

正如sagarpandya82所指出的,您还可以使用or方法简单地检查所有内容是否为
nil
,或者任何内容是否为
nil
,而不是删除
nil
s

重述:

original_array = [[nil, nil],[1, nil, 2], [1, 2, 3]]
original_array.reject { |arr| arr.all?(:nil) } # returns [[1, nil, 2], [1, 2, 3]]
original_array.reject { |arr| arr.compact.empty? } # returns [[1, nil, 2], [1, 2, 3]]
original_array.reject { |arr| arr.any?(:nil) } # returns [[1, 2, 3]]
original_array.reject { |arr| arr.compact!.empty? } # returns [[1, 2, 3], [1, 2]]

假设您只对二维阵列感兴趣,那么:

Rid子数组仅由
nil
s组成:

arr.reject { |arr| arr.all?(&:nil?) }
arr.reject { |arr| arr.any?(&:nil?) }
由任何
nil
s组成的Rid子数组:

arr.reject { |arr| arr.all?(&:nil?) }
arr.reject { |arr| arr.any?(&:nil?) }
  • compact
    将从数组中删除
    nil
    元素
  • map
    将运行数组中的每个项,并通过对数组的项应用代码返回一个新数组。请注意,在您的示例中,数组的元素本身是。。。数组
  • reject
    将返回一个新数组,其中不包含给定代码回答为“false”的元素
  • select
    将返回一个新数组,其中包含给定代码“喜欢”的元素(与拒绝相反)
因此,如果您只想从数组及其子数组(但不是子数组)中删除所有
nil
s
,您可以调用

list = [[1,2], [nil], [1,nil,2]]
list.map(&:compact).reject(&:empty?) #=> [[1,2], [1,2]]
这和

compacted_list = list.map do |element|
  element.compact
end
non_empty_list = compacted_list.reject do |element|
  element.empty?
end
如果要从列表/数组中删除所有
[nil,nil]
条目

list.reject{|element| element == [nil, nil]}
或者如果更多的是关于选择非nil元素(这实际上只是关于意图揭示代码)


大多数函数都有一个
对应项(如
拒绝!
),进行适当的修改,这意味着您不必指定返回值(如
新列表=旧列表。拒绝()
)。

对该问题似乎有不同的解释

如问题示例所示,如果包含一个
nil
的所有元素(数组)仅包含
nil
s,并且要排除这些元素,则可以这样做:

[[nil, nil], [1, 2], [nil, nil], [nil, nil]].select(&:first)
  #=> [!1, 2]]
[[3, nil], [1, 2], [3, 4, 5, nil]].reject { |a| a.any?(&:nil?) }
  #=> [!1, 2]]
[[3, nil], [1, 2], [nil], [nil, 3, 4]].map(&:compact)
  #=> [[3], [1, 2], [], [3, 4]]
[[3, nil], [1, 2], [nil], [nil, 3, 4]].map(&:compact).reject(&:empty?)
  #=> [[3], [1, 2], [3, 4]]
如果要排除包含至少一个
nil
的所有元素,则会执行以下操作:

[[nil, nil], [1, 2], [nil, nil], [nil, nil]].select(&:first)
  #=> [!1, 2]]
[[3, nil], [1, 2], [3, 4, 5, nil]].reject { |a| a.any?(&:nil?) }
  #=> [!1, 2]]
[[3, nil], [1, 2], [nil], [nil, 3, 4]].map(&:compact)
  #=> [[3], [1, 2], [], [3, 4]]
[[3, nil], [1, 2], [nil], [nil, 3, 4]].map(&:compact).reject(&:empty?)
  #=> [[3], [1, 2], [3, 4]]
如果要从每个元素中删除所有
nil
s,则可以执行以下操作:

[[nil, nil], [1, 2], [nil, nil], [nil, nil]].select(&:first)
  #=> [!1, 2]]
[[3, nil], [1, 2], [3, 4, 5, nil]].reject { |a| a.any?(&:nil?) }
  #=> [!1, 2]]
[[3, nil], [1, 2], [nil], [nil, 3, 4]].map(&:compact)
  #=> [[3], [1, 2], [], [3, 4]]
[[3, nil], [1, 2], [nil], [nil, 3, 4]].map(&:compact).reject(&:empty?)
  #=> [[3], [1, 2], [3, 4]]
如果要从每个元素中删除所有
nil
s,然后删除所有空数组,则可以这样做:

[[nil, nil], [1, 2], [nil, nil], [nil, nil]].select(&:first)
  #=> [!1, 2]]
[[3, nil], [1, 2], [3, 4, 5, nil]].reject { |a| a.any?(&:nil?) }
  #=> [!1, 2]]
[[3, nil], [1, 2], [nil], [nil, 3, 4]].map(&:compact)
  #=> [[3], [1, 2], [], [3, 4]]
[[3, nil], [1, 2], [nil], [nil, 3, 4]].map(&:compact).reject(&:empty?)
  #=> [[3], [1, 2], [3, 4]]
我最近在看一个RubyGem,它提供了很多核心ruby语言扩展

他们给出的其中一个例子是该方法,我将在下面展示:

arr = ["a", ["b", "c", nil], nil]
arr.recurse{ |a| a.compact! }
#=> ["a", ["b", "c"]]
在您的情况下,这将完成大约一半的工作—您还希望删除非空数组

Facets通过修补核心Ruby方法来工作。这意味着只要运行
require'facets/array/recurse'
,任何先前定义的
array\recurse
方法都将被覆盖。修补核心方法通常是不明智的,因为可能存在命名冲突

尽管如此,它仍然是一种有用的方法,而且它的定义方式很简单,它将数组作为参数,而不是对
self
的值进行操作。然后,您可以使用它来定义两种方法,它们共同实现您的目标:

module ArrayUtils
  def recurse(array, *types, &block)
    types = [array.class] if types.empty?
    a = array.reduce([]) do |arr, value|
      case value
      when *types
        arr << recurse(value, *types, &block)
      else
        arr << value
      end
      arr
    end
    yield a
  end

  def recursive_compact(array)
    recurse(array, &:compact)
  end

  def recursive_remove_nonempty(array)
    recurse(array) do |arr|
      arr.reject do |x|
        x.is_a?(Array) && x.empty?
      end
    end
  end
end
跑步

original: [[nil, nil], [1, 2], [nil, nil], [nil, nil]]
compacted: [[], [1, 2], [], []]
nonempties: [[1, 2]]

子数组
[1,2,nil,3]
怎么样?很高兴看到这样做的递归方式,虽然听起来OP想要一个方法链接解决方案,但递归解决方案肯定可以通过方法调用实现。
&:first
做什么@SunilD.,这实际上与
arr.select{| pair | pair.first}
相同
pair。如果第一个
既不等于
nil
也不等于
false
,则第一个
为真。因此,如果
a
是真实的,则选择元素
[a,b]
。根据问题中的示例,我假设
b
nil
当且仅当
a
nil