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

时间:2019-05-17 17:39:54

标签: ruby

我正在尝试从字符串数组中找出如何比较基于字符的字符串。例如,有以下内容:

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"]

因此匹配将保持第一个出现,然后对不匹配的内容进行排序。

2 个答案:

答案 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所述,您可能需要反转输出以符合期望。

可能可以使用其他reduceeach等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)