Ruby 嵌套迭代以匹配数组中的字符串



我试图从字符串数组中找出如何根据字符比较字符串。例如,有以下几点:

arr = [4, "string", "gnirts", "strign", "ta", "atc"]

在这种情况下,"ta"和"atc"与其他字符串不匹配。但是"字符串","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 和字符串(因为其他人与它匹配并且字符串排在第一位)。

那么,我如何最终比较数组中的字符串并保留第一个字符串呢?

编辑: 输入类似于 [4, "string", "gnirts", "strign", "ta", "atc"] 输出数组将是

["atc", "ta", "string"]

因此,匹配将保留第一个礼物,然后对不匹配的礼物进行排序。

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 提到的,您可能希望反转输出以匹配预期。

可以使用其他 Enumerable 方法(如reduceeach等)来做到这一点,但是group_by更习惯,我建议阅读 Ruby 的 Enumerable 类,因为如果您知道所有可用的方法,您可以使用方法链完成很多工作。

require 'set'
arr.grep(String).uniq { |obj| obj.each_char.to_set }.sort_by(&:size)
#=> ["ta", "atc", "string"] 

Array#uniq 的文档指出,"self按顺序遍历,并保留第一次出现",这意味着,在"string""gnirts""strign"中,"string"在数组中具有最小的索引(1),因此它是uniq保留的索引。

可以用obj.each_char.sort替换obj.each_char.to_set,但如果数组很大,后者的效率会降低。

如果已知只有一个非字符串并且它是数组的第一个元素,请将grep(String)替换为drop(1)

最新更新