Я пытаюсь выяснить из массива строк, как сравнивать строки на основе символов. Так, например, есть следующее:
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)
если известно, что существует ровно одна нестроковая строка, и это первый элемент массива.