Есть ли однострочный Ruby для вложенных массивов Ruby join () с другой строкой join () для внутренних / внешних массивов? - PullRequest
1 голос
/ 04 августа 2020

Для:

a = [ ["John", "Doe"], ["Sue", "Smith"]]

Желаемый результат: "John Doe, Sue Smith"

Код грубой силы прост:

a = [ ["John", "Doe"], ["Sue", "Smith"]]
name_array = []
a.each { |n| name_array << n.join(" ") } # first, inner join w/ space
s = name_array.join(", ") # then, outer join with comma

Но есть ли еще succint (однострочный?) для выполнения sh это в Ruby?

Ответы [ 3 ]

1 голос
/ 04 августа 2020

Сопоставление и объединение

Вы можете сделать это с помощью Array # map и Array # join . Например, в Ruby 2.7.1:

array = [["John", "Doe"], ["Sue", "Smith"]]
array.map { _1.join ?\s }.join ", "
#=> "John Doe, Sue Smith"

Если вы не используете недавний Ruby или предпочитаете более явный синтаксис, вы можете сделать то же самое, например:

array.map { |subarray| subarray.join " " }.join ", "
#=> "John Doe, Sue Smith"

Конечно, есть и другие способы сделать это, но этот однострочный вариант, кажется, соответствует вашим примерам и варианту использования.

0 голосов
/ 04 августа 2020
a = [["John", "Doe"], ["Sue", "Smith"], ["Melba", "Jones"]]

Очевидный способ сделать это, о котором говорили другие, это:

a.map { |arr| arr.join(' ') }.join(', ')
  #=> "John Doe, Sue Smith, Melba Jones"

В качестве упражнения вот три способа сделать это без использования Array#map

Используйте Enumerable # reduce (aka inject)

a.drop(1).reduce(a.first.join(' ')) { |s,name| s + ", %s %s" % name }
  #=> "John Doe, Sue Smith, Melba Jones"

Используйте рекурсию

def doit((name, *rest))
  rest.empty? ? name.join(' ') : "%s %s, %s" % [*name, doit(rest)]
end
doit(a)
  #=> "John Doe, Sue Smith, Melba Jones"

Свести, объединить пробелом, использовать String # gsub для вставки запятых

r = /
    \w+[ ]\w+ # match two words separated by a space
    (?=[ ])   # positive lookahead asserts that next character is a space
    \K        # reset start of match to current location and discard all
              # previously matched characters from match that is returned
    /x        # free-spacing regex definition mode

a.flatten.join(' ').gsub(r, ',')
  #=> "John Doe, Sue Smith, Melba Jones"
0 голосов
/ 04 августа 2020

Если вы хотите построить новый массив из существующего массива (или любого перечисляемого), на самом деле вы хотите использовать Enumerable # map .

Map выполняет итерацию по существующему массиву, запускает блок и собирает результаты.

 result = a.map { |people| people.join(' ') }.join(', ')

Разбивка:

intermediate = a.map { |people| people.join(' ') } 
# transforms
#   [ ["John", "Doe"], ["Sue", "Smith"]]
# into
#   [ "John Doe", "Sue Smith" ]
# we take the result of that and run
result = intermediate.join(', ')
# which then transforms your array in the the final string:
# "John Doe, Sue Smith"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...