Ruby вложенная итерация для сопоставления строк в массиве

Я пытаюсь выяснить из массива строк, как сравнивать строки на основе символов. Так, например, есть следующее:

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

В этом случае «ta» и «atc» не совпадают с другими строками. А вот «нитки», «гнифы», «стринги» совпадают.

Моей первой мыслью было бы разбить массив на части, сделать проверку длины. Затем сравните строки и сохраните первый подарок.

Я знаю, что меня не волнует 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 ответа


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, такие как group_by , each и т. Д. Однако group_by более идиоматичен, и я бы рекомендовал прочитать класс Enumerable в Ruby, потому что вы можете многое сделать с помощью цепочки методов, если знаете все методы которые доступны для вас.


require 'set'

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

Можно заменить obj.each_char.to_set на obj.each_char.sort но это менее эффективно, если массив большой.

Замените grep(String) на drop(1) если известно, что существует ровно одна нестроковая строка, и это первый элемент массива.


Есть идеи?

10000