我正在尝试从字符串数组中找出如何比较基于字符的字符串。例如,有以下内容:
arr = [4, "string", "gnirts", "strign", "ta", "atc"]
在这种情况下,“ ta”和“ atc”与其他字符串不匹配。但是“ string”,“ gnirts”,“ strign”匹配。
我的第一个想法是将数组分开,进行长度检查。然后比较字符串并保持第一个存在。
我知道我不在乎4。它只是指示字符串的数目,因此我可以执行arr.shift(1)。
我知道我可以做类似string.chars.sort的事情,但是如何比较数组中的字符串?
我在想类似的东西:
arr.each_with_index do |value, index|
index.each do |item|
if value.chars.sort == item
return value
end
end
那绝对不行。
我想要最终看到的东西随后将在数组上排序,所以我最终得到的是atc,gnirts和string(因为其他匹配的对象是string,字符串优先出现)。
那我如何最终比较数组中的字符串并保持第一个数字不变?
编辑: 输入将类似于[4,“ string”,“ gnirts”,“ strign”,“ ta”,“ atc”] 输出数组将是
["atc", "ta", "string"]
因此匹配将保持第一个出现,然后对不匹配的内容进行排序。
答案 0 :(得分:4)
input = [4, "string", "gnirts", "strign", "ta", "atc"]
input.
drop(1).
group_by { |str| str.chars.sort.join }.
values.
map(&:first)
# => ["string", "ta", "atc"]
逐行浏览:
input.
drop(1).
# => ["string", "gnirts", "strign", "ta", "atc"]]
group_by { |str| str.chars.sort.join }.
# => {
# "ginrst" => ["string", "gnirts", "strign"],
# "at" => ["ta"],
# "act" => ["atc"]
# }
values.
# => [
# ["string", "gnirts", "strign"],
# ["ta"],
# ["atc"]
# ]
map(&:first)
# => ["string", "ta", "atc"]
如lacostenycoder所述,您可能需要反转输出以符合期望。
可能可以使用其他reduce
,each
等Enumerable方法进行此操作。但是,group_by
较为惯用,我建议您阅读Ruby的Enumerable类,因为您如果您知道所有可用的方法,就可以通过方法链接完成很多工作。
答案 1 :(得分:3)
require 'set'
arr.grep(String).uniq { |obj| obj.each_char.to_set }.sort_by(&:size)
#=> ["ta", "atc", "string"]
Array#uniq的文档指出,“ self
被依次遍历,并且第一次出现会保留。”,这意味着在"string"
,"gnirts"
和{ {1}},"strign"
在数组("string"
)中具有最小的索引,因此它是1
保留的索引。
一个可以用uniq
代替obj.each_char.to_set
,但是如果数组很大,后者的效率会降低。
如果已知完全有一个非字符串且它是数组的第一个元素,则用obj.each_char.sort
替换grep(String)
。