2014-11-21 2 views
1

Возможно ли «суммировать» разнообразные перечислимые числа, когда они являются строковым режимом? на пример вроде этого? (Ну, я знаю, это не работает.)Как «суммировать» перечисления в Ruby

(('a'..'z') + ('A'..'Z')).to_a 

примечание: Я спрашиваю о том, чтобы массив строк символов от А до Я и от А до Я все вместе. О строковом режиме Я имею в виду, что символы появятся как ["a", "b", ....., "Y", "Z"]

+3

Каков ваш ожидаемый результат? Массив из 52 элементов (всех верхних и нижних букв)? –

+0

есть. Что-то вроде того. – RadW2020

+0

Каким будет ожидаемый выход? Вы спрашиваете, как снять операцию добавления над двумя 'Enumerable'? А что такое «строковый режим»? –

ответ

9

Вы можете использовать splat оператор:

[*('A'..'Z'), *('a'..'z')] 
+3

Даже работы без скобок: '[* 'A' .. 'Z', * 'a' .. 'z']' – Stefan

+0

К сожалению, в соответствии с обновленным вопросом этот ответ больше не верен. –

+0

Это блестяще и работает префектно и элегантно для меня. Извините, если мой английский создал недоразумения. – RadW2020

4

Нравится?

[('a'..'z'), ('A'..'Z')].map(&:to_a).flatten 

Или это?

('a'..'z').to_a + ('A'..'Z').to_a 
+3

'[('A' .. 'Z'), ('a'. .'z ')]. flat_map (&: to_a) 'короче;) –

+0

Вы правы. Я всегда забываю «flat_map» ... – spickermann

+0

К сожалению, по обновленному вопросу этот ответ больше не верен. –

2

не ответить, но бенчмаркинг ответов:

require 'benchmark' 

n = 100000 
Benchmark.bm do |x| 
    x.report("flat_map : ") { n.times do ; [('A'..'Z'), ('a'..'z')].flat_map(&:to_a) ; end } 
    x.report("map.flatten: ") { n.times do ; [('A'..'Z'), ('a'..'z')].map(&:to_a).flatten ; end } 
    x.report("splat  : ") { n.times do ; [*('A'..'Z'), *('a'..'z')] ; end } 
    x.report("concat arr : ") { n.times do ; ('A'..'Z').to_a + ('a'..'z').to_a ; end } 
end 

Результат:

#=>  user  system  total  real 
#=> flat_map : 0.858000 0.000000 0.858000 ( 0.883630) 
#=> map.flatten: 1.170000 0.016000 1.186000 ( 1.200421) 
#=> splat  : 0.858000 0.000000 0.858000 ( 0.857728) 
#=> concat arr : 0.812000 0.000000 0.812000 ( 0.822861) 
+0

К сожалению, в соответствии с обновленным вопросом, этот ответ больше не верен. –

+0

Почему вы так говорите? Все четыре варианта делают то же самое и идеально для цели заданного вопроса. – RadW2020

+0

@ RadW2020: Ну, вы изменили свой вопрос, чтобы спросить о противоположном заказе, чем раньше. Когда я написал свой ответ и написал этот комментарий, ваш вопрос спросил о том, как получить массивы в обратном порядке. Теперь ваш вопрос задает вопрос о том, как получить их в том порядке, в котором они появляются. Конечно, все, что написано * до того, как вы сделали это изменение, больше не будет иметь никакого смысла. –

0

Поскольку вы хотите элементы из первыйRange быть на конце выходного сигнала Array и элементы последнейRange быть в начала выхода Array, но все же сохранить тот же порядок в пределах каждого Range, я бы сделать это так (что также обобщает хорошо более чем двух Enumerable с):

def backwards_concat(*enums) 
    enums.reverse.map(&:to_a).inject([], &:concat) 
end 

backwards_concat('A'..'Z', 'a'..'z') 
0
['a'..'z'].concat(['A'..'Z']) 

Это, вероятно, дш ckest способ сделать это.

+0

это неправильно. Это ваш выход «a..zA..Z». concat - для строк. – RadW2020

0

О режиме струнной Я имею в виду, что символы будут появляется как [ "а", "б", ....., "Y", "Z"]

Чтобы ответить на выше :

Array('a'..'z').concat Array('A'..'Z')