如果它们相同,则删除二维数组中的第一个值

时间:2019-09-16 11:55:40

标签: ruby-on-rails ruby

我正在使用这种类型的数组

array = [
  ["01000290056", 601, "Individuālo dzīvojamo māju apbūve", nil, 0],
  ["01000290056", 703, "Se┼Īu l─½dz se┼Īpadsmit st─üvu daudzdz─½vok─╝u m─üju apb┼½ve", nil, 0],
  ["01000290056", 801, "Komercdarbības objektu apbūve", nil, 0],
  ["01000290056", 1001, "R┼½pniecisk─üs ra┼Šo┼Īanas uz┼å─ōmumu apb┼½ve", nil, 0],
  ["01000290056", 1105, "Atsevi┼Ī─Ęi nodal─½tas atkl─ütas autost─üvvietas", nil, 0]
]

在这种情况下,01000290056在重复。

最后,我需要得到这样的东西

[["01000290056", 601, "Individuālo dzīvojamo māju apbūve", nil, 0],
 [nil, 703, "Se┼Īu l─½dz se┼Īpadsmit st─üvu daudzdz─½vok─╝u m─üju apb┼½ve", nil, 0],
 [nil, 801, "Komercdarbības objektu apbūve", nil, 0], 
 [nil, 1001, "R┼½pniecisk─üs ra┼Šo┼Īanas uz┼å─ōmumu apb┼½ve", nil, 0],
 [nil, 1105, "Atsevi┼Ī─Ęi nodal─½tas atkl─ütas autost─üvvietas", nil, 0]]

因此,应删除01000290056的所有重复值。

我正在尝试通过这种方式完成

array.each_with_index.map do |v,i|
  v.each_with_index.map do |k,j|
    if (i-1>=0 && k == array[i-1][j])
      k
    elsif (i+1 < array.length && k == array[i+1][j])
      k
    else
      nil
    end
  end
end

但这会给我返回:

[["01000290056", nil, nil, nil, 0],
 ["01000290056", nil, nil, nil, 0],
 ["01000290056", nil, nil, nil, 0],
 ["01000290056", nil, nil, nil, 0],
 ["01000290056", nil, nil, nil, 0]]

我的错误是什么?

3 个答案:

答案 0 :(得分:1)

  

我的错误是什么?

根据输入和输出判断,您忘记了要执行的操作,然后开始遍历每个子数组的每个元素。

一种避免混淆的常见方法是use comments for planning

这是我的解决方法:

def remove_firsts(arr)
  # Make sure first elements in sub-arrays are equal
  if arr.map { |sub_arr| sub_arr[0] }.uniq.length == 1
    # iterate through all elements except first
    (1...arr.length).each do |i|
      arr[i][0] = nil
    end
  end
  return arr
end

答案 1 :(得分:1)

迭代内部子数组的每个元素并仅保留相同的值时,您将映射nil。

我建议这个更简单的解决方案应该按照您的要求进行:

dups = []
array.map{|a| dups.include?(a[0]) ? a[0] = nil : dups << a[0]; a }

基本上,我们不需要循环整个内部数组,我只是检查第一个元素,如果已经满足,请将其设置为nil。

请注意,此映射函数将作用于原始数组,对其进行变异,如果要保留原始数据,则应按照我的建议在映射之前复制它。

答案 2 :(得分:0)

require 'set'

f = Set.new

array.map do |a|
  f.add?(a.first) ? a : [nil, *a.drop(1)]
end
  #=> [["01000290056", 601, "Individuālo dzīvojamo māju apbūve", nil, 0],
  #    [nil, 703, "Se┼Īu l─½dz se┼Īpadsmit...", nil, 0],
  #    [nil, 801, "Komercdarbības objektu apbūve", nil, 0],
  #    [nil, 1001, "R┼½pniecisk─üs ra┼Šo┼Īanas uz┼å─ōmumu apb┼½ve", nil, 0],
  #    [nil, 1105, "Atsevi┼Ī─Ęi nodal─½tas atkl─ütas autost─üvvietas", nil, 0]]

这不会修改或变异 array

如果要修改array,则可以使用以下内容。

f = Set.new

array.each { |a| a[0] = nil unless f.add?(a.first) }
array

f设置为一组而不是数组可以提高查找速度,如果array很大,这可能很重要。

请参见Set::newSet#add?Array#drop

相关问题