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

匹配数组中字符串的Ruby嵌套迭代,ruby,Ruby,我试图从字符串数组中找出如何根据字符比较字符串。例如,有以下几点: arr = [4, "string", "gnirts", "strign", "ta", "atc"] 在这种情况下,“ta”和“atc”与其他字符串不匹配。但是“字符串”、“gnits”、“strign”匹配 我的第一个想法是将阵列分开,进行长度检查。然后比较字符串并保留第一个字符串 我知道我不在乎那四个。它只是指示字符串的数量,以便我可以执行arr.shift(1) 我知道我可以做一些类似string.chars.sor

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

arr = [4, "string", "gnirts", "strign", "ta", "atc"]
在这种情况下,“ta”和“atc”与其他字符串不匹配。但是“字符串”、“gnits”、“strign”匹配

我的第一个想法是将阵列分开,进行长度检查。然后比较字符串并保留第一个字符串

我知道我不在乎那四个。它只是指示字符串的数量,以便我可以执行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”、“gnits”、“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所提到的,您可能希望反转输出以匹配预期

可能可以使用其他可枚举方法来实现这一点,例如
reduce
each
,等等。不过更为惯用的是,我建议您阅读Ruby的可枚举类,因为如果您知道所有可用的方法,您可以通过方法链接完成很多工作

require 'set'

arr.grep(String).uniq { |obj| obj.each_char.to_set }.sort_by(&:size)
  #=> ["ta", "atc", "string"] 
doc for states,“
self
按顺序遍历,并保留第一次出现的内容。”,这意味着在
字符串
gnits
strign
中,
字符串
在数组中具有最小的索引(
1
),因此它是
uniq
保留的索引

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


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

给定
arr
,是否可以清楚地发布预期输出?使用预期输出进行ArrayeEditiond post。如果您没有解释“ta”和“atc”中的“match”是什么意思,“ta”和“atc”与其他字符串不匹配”,那么将删除基于第一个出现然后按字母顺序排序的匹配字符串。事实上,直到我读到马克斯的答案,我才明白这一点。如果一个字符串是另一个的字谜,则需要说明两个字符串匹配。实际上,您有三个问题可以归结为一个:“如何在开始时跳过
4
?”;“在每组互为字谜的字符串中,如何仅选择组中的第一个?”;以及“在回答前两个问题后,如何按长度对结果数组排序?”。一般来说,最好将多部分问题限制在中心问题上,尤其是当其他问题(这里是第一个和最后一个)的答案非常明显时。可能根据OPs示例添加
.reverse
str.chars.sort.join
smart@我有点惊讶没有一个
String#sort
方法可以使用
input.drop(1)
input[1..-1]
input[1..]
而不是破坏性的
shift
操作。@CarySwoveland我同意你的所有观点,除了使用uniq而不是group\u By的建议之外:
arr.grep(String)
是一种只筛选字符串类型对象的简便方法。对于类型检查,通常最好执行
obj.is_a?(String)
而不是文本类比较
obj.class==String
。值得注意的是,
String===obj
是做这件事的同等方式,而且只有在
Class#===
是特例时,才按照这个顺序来做。@tadman,谢谢。我编辑。我喜欢
String===obj
,但担心一些读者可能不理解它,而且总是有可能无意中点击该键两次而不是三次?字符串
应该是obj.is_a?字符串