Ruby вложенная итерация для сопоставления строк в массиве - PullRequest
0 голосов
/ 17 мая 2019

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

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 и string (потому что остальные совпадают с этим, и string будет первым).

Так как же в конечном итоге сравнить строки в массиве и сохранить первую в числовом виде?

EDIT: Ввод будет что-то вроде [4, "string", "gnirts", "strign", "ta", "atc"] Выходной массив будет

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

Таким образом, сопоставление сохранит первый подарок, а затем отсортирует по несоответствующим.

Ответы [ 2 ]

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

3 голосов
/ 17 мая 2019
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.to_set на obj.each_char.sort, нопоследний менее эффективен, если массив большой.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...