我已经将excel解析为数组数组。新名称将添加到Excel的底部,其中一些可能已存在。所以我想首先对正在运行的数组进行排序。 然后,我想基于匹配前两个元素(以及第三个元素,如果它不为空)来删除任何重复项。保留的数组是没有第四个空元素的数组。
array = []
sorted = []
array << ["John", "Smith", "null"] + [ "null", "null", "y", "y", "n", "n", "n"]
array << ["Mary", "Jones","mary@addy.com," "fsgdseg", "comment", "y", "y", "n", "n", "n"]
array << ["Peter", "Ross", "null", "adfgehs", "comment", "y", "y", "n", "n", "n"]
array << ["John", "Smith", "john@smith.com", "dfsgfsdgsd", "comment", "y", "y", "n", "n", "n"]
array.sort_by {|e| [e[0], e[3]]} .each {|line| sorted << line }
sorted.each{ |i| p i}
#=> ["John", "Smith", "john@smith.com", "dfsgfsdgsd", "comment", "y", "y", "n", "n", "n"]
#=> ["John", "Smith", "null", "null", "null", "y", "y", "n", "n", "n"]
#=> ["Mary", "Jones", "mary@addy.com,fsgdseg", "comment", "y", "y", "n", "n", "n"]
#=> ["Peter", "Ross", "null", "adfgehs", "comment", "y", "y", "n", "n", "n"]
现在我想删除元素0,1匹配的数组。 2(如果有)&amp;删除元素3不为空的那个。
答案 0 :(得分:4)
解释问题
我认为问题如下。数组(数组的元素)将被分组。如果每个数组的前三个元素相同或前两个元素相同且第三个元素等于&#34; null&#34;则两个数组在同一组中。对于一个或两个阵列。如果一个组由一个数组组成,则该组将被该数组替换。如果一个组包含两个或多个数组,则其中一个数组中的第四个元素将不会是&#34; null&#34;,并且该组将被该数组替换..
如果这种解释不正确,那么修改下面的代码以符合正确的解释应该不难。
<强>代码强>
def select_arrays(array)
h = array.group_by { |a| a[0,3] }
keys = h.keys
h.each_key do |k|
next unless k[2]=="null"
key = keys.find { |kk| (k!=kk) && k[0,2]==kk[0,2] }
h[key].concat(h.delete(k)) if key
end.values.map { |a|
(a.size==1) ? a.first : a.find { |e| e[3] != "null"} }.sort
end
示例强>
array = [
["John", "Smith", "null", "null", "null", "y", "y", "n", "n", "n"],
["Peter", "Ross", "null", "adfgehs", "comment", "y", "y", "n", "n", "n"],
["Mary", "Jones", "mary@addy.com", "fsgdseg", "comment", "y", "y", "n", "n", "n"],
["John", "Smith", "john@smith.com", "dfsgfsdgsd", "comment", "y", "y", "n", "n", "n"],
["Peter", "Ross", "Bubba", "null", "comment", "y", "y", "n", "n", "n"],
["John", "Smith", "john@smith.com", "null", "comment", "y", "y", "n", "n", "n"]
]
select_arrays(array)
#=> [["John", "Smith", "john@smith.com", "dfsgfsdgsd",
# "comment", "y", "y", "n", "n", "n"],
# ["Mary", "Jones", "mary@addy.com", "fsgdseg",
# "comment", "y", "y", "n", "n", "n"],
# ["Peter", "Ross", "null", "adfgehs",
# "comment", "y", "y", "n", "n", "n"]]
<强>解释强>
步骤如下:
x
数组中。x
(数组)的每个元素转换为单个数组。如果元素y
只有一个元素,请转换为y.first
;否则选择arr
的{{1}}元素y
。对于上面的arr[2] != "null"
,我们计算:
array
枚举器的每个元素都由Hash#each传递给块,并分配给块变量h = array.group_by { |a| a[0,3] }
#=> {["John", "Smith", "null"]=>
# [["John", "Smith", "null", "null",
# "null", "y", "y", "n", "n", "n"]],
# ["Peter", "Ross", "null"]=>
# [["Peter", "Ross", "null", "adfgehs",
# "comment", "y", "y", "n", "n", "n"]],
# ["Mary", "Jones", "mary@addy.com"]=>
# [["Mary", "Jones", "mary@addy.com", "fsgdseg",
# "comment", "y", "y", "n", "n", "n"]],
# ["John", "Smith", "john@smith.com"]=>
# [["John", "Smith", "john@smith.com", "dfsgfsdgsd",
# "comment", "y", "y", "n", "n", "n"],
# ["John", "Smith", "john@smith.com", "null",
# "comment", "y", "y", "n", "n", "n"]],
# ["Peter", "Ross", "Bubba"]=>
# [["Peter", "Ross", "Bubba", "null",
# "comment", "y", "y", "n", "n", "n"]]}
keys = h.keys
#=> [["John", "Smith", "null"],
# ["Peter", "Ross", "null"],
# ["Mary", "Jones", "mary@addy.com"],
# ["John", "Smith", "john@smith.com"],
# ["Peter", "Ross", "Bubba"]]
enum = h.each_key
#=> #<Enumerator: {["John", "Smith", "null"]=>[["John", "Smith",...
# ...}:each_key>
。我们可以使用Enumerator#next:
k
作为k = enum.next
#=> ["John", "Smith", "null"]
next unless k[2]=="null"
,我们不会走到循环的末尾。
k[2] == "null"
我们找到了与前两个元素匹配的其他键,因此我们将key = keys.find { |kk| (k!=kk) && k[0,2]==kk[0,2] }
#=> ["John", "Smith", "john@smith.com"]
添加到h[k]
并删除键h[key]
:
k
我们确认已删除一个密钥:
h[key].concat(h.delete(k)) if key
#=> [["John", "Smith", "john@smith.com", "dfsgfsdgsd",
# "comment", "y", "y", "n", "n", "n"],
# ["John", "Smith", "john@smith.com", "null",
# "comment", "y", "y", "n", "n", "n"],
# ["John", "Smith", "null", "null",
# "null", "y", "y", "n", "n", "n"]]
现在将h.each_key.to_a
#=> [["Peter", "Ross", "null"],
# ["Mary", "Jones", "mary@addy.com"],
# ["John", "Smith", "john@smith.com"],
# ["Peter", "Ross", "Bubba"]]
的下一个元素传递到块中:
enum
现在:
k = enum.next
#=> ["Peter", "Ross", "null"]
next unless k[2]=="null"
key = keys.find { |kk| (k!=kk) && k[0,2]==kk[0,2] }
#=> ["Peter", "Ross", "Bubba"]
h[key].concat(h.delete(k)) if key
我们处理h #=> {["Mary", "Jones", "mary@addy.com"]=>
# [["Mary", "Jones", "mary@addy.com", "fsgdseg",
# "comment", "y", "y", "n", "n", "n"]],
# ["John", "Smith", "john@smith.com"]=>
# [["John", "Smith", "john@smith.com", "dfsgfsdgsd",
# "comment", "y", "y", "n", "n", "n"],
# ["John", "Smith", "john@smith.com", "null",
# "comment", "y", "y", "n", "n", "n"],
# ["John", "Smith", "null", "null",
# "null", "y", "y", "n", "n", "n"]],
# ["Peter", "Ross", "Bubba"]=>
# [["Peter", "Ross", "Bubba", "null",
# "comment", "y", "y", "n", "n", "n"],
# ["Peter", "Ross", "null", "adfgehs",
# "comment", "y", "y", "n", "n", "n"]]}
的其他元素时不再对h
进行更改,因为enum
代表所有这些值。
现在提取k[2] != "null"
:
h
现在浏览一下这些值。如果值包含单个元素,则用该元素替换该数组; else用v = h.values
#=> [[["Mary", "Jones", "mary@addy.com", "fsgdseg",
# "comment", "y", "y", "n", "n", "n"]],
# [["John", "Smith", "john@smith.com", "dfsgfsdgsd",
# "comment", "y", "y", "n", "n", "n"],
# ["John", "Smith", "john@smith.com", "null",
# "comment", "y", "y", "n", "n", "n"],
# ["John", "Smith", "null", "null",
# "null", "y", "y", "n", "n", "n"]],
# [["Peter", "Ross", "Bubba", "null",
# "comment", "y", "y", "n", "n", "n"],
# ["Peter", "Ross", "null", "adfgehs",
# "comment", "y", "y", "n", "n", "n"]]]
:
a
替换数组
a[3] != "null"
最后,如果需要,排序:
arr = v.map { |a| (a.size==1) ? a.first : a.find { |e| e[3] != "null"} }
#=> [["Mary", "Jones", "mary@addy.com", "fsgdseg",
# "comment", "y", "y", "n", "n", "n"],
# ["John", "Smith", "john@smith.com", "dfsgfsdgsd",
# "comment", "y", "y", "n", "n", "n"],
# ["Peter", "Ross", "null", "adfgehs",
# "comment", "y", "y", "n", "n", "n"]]
产生上面例子中显示的结果。
答案 1 :(得分:2)
也许我不明白这个问题,但也许这就是你想要的。
所以也许这个?
array, sorted = [], []
array << ["John", "Smith", "null"] + [ "null", "null", "y", "y", "n", "n", "n"]
array << ["Mary", "Jones","mary@addy.com," "fsgdseg", "comment", "y", "y", "n", "n", "n"]
array << ["Peter", "Ross", "null", "adfgehs", "comment", "y", "y", "n", "n", "n"]
array << ["John", "Smith", "john@smith.com", "dfsgfsdgsd", "comment", "y", "y", "n", "n", "n"]
is_define = {}
array.sort_by {|e| [e[0], e[3]]} .each {|line|
unless line[3].to_s == "null"
full_name_a = line[0..1]
if is_define.has_key?(full_name_a)
unless is_define[full_name_a].include?(line[3])
is_define[full_name_a] << line[3]
sorted << line
end
else
is_define[full_name_a] = [line[3]]
sorted << line
end
end
}
sorted.each do |a| p a end
# => ["John", "Smith", "john@smith.com", "dfsgfsdgsd", "comment", "y", "y", "n", "n", "n"]
# => ["Mary", "Jones", "mary@addy.com,fsgdseg", "comment", "y", "y", "n", "n", "n"]
# => ["Peter", "Ross", "null", "adfgehs", "comment", "y", "y", "n", "n", "n"]
我有结果,所以我更新了源代码。