2014-09-04 6 views
0

У меня есть массив, как следующие:Массив массивов, отдельных массивов рубин

[["red", "green", "blue"], ["small", "large", "medium"], ["loose", "tight"]] 

мне нужно вытащить все из этих массивов из родителей, в отдельные массивы, например:

["red", "green", "blue"] ["small", "large", "medium"] ["loose", "tight"] 

Программа не всегда знает, сколько дочерних массивов будет в родительском массиве, потому что они динамически создаются.

Конечной целью является сделать первый массив (красный, зеленый, синий, и т.д. ...) и вызвать .product на него, проходя во всех последующих массивах, по отдельности, так что я в конечном итоге следующее:

"red small loose", "red small right", "red large loose", etc..

+1

Возможно ли, да. Возникает вопрос, как вы хотите хранить каждый массив? Что вы делаете с этими данными, что нужно отделить? –

+0

Я бы хотел, чтобы дочерние массивы оставались массивами, но не были в родительском. Я пытаюсь вызвать 'product' в первом массиве и передать остальные массивы в отдельности. – jmcharnes

+0

@jmcharnes Возможно, вы можете отредактировать свой вопрос, чтобы четко объяснить эту цель в деталях. (Это определенно возможно, и не особенно сложно.) – Ajedi32

ответ

4

Это будет работать:

arrays = [["red", "green", "blue"], ["small", "large", "medium"], ["loose", "tight"]] 

first, *others = arrays 
first.product(*others).map { |s| s.join(' ') } 
#=> ["red small loose", "red small tight", "red large loose", "red large tight", "red medium loose", "red medium tight", "green small loose", "green small tight", "green large loose", "green large tight", "green medium loose", "green medium tight", "blue small loose", "blue small tight", "blue large loose", "blue large tight", "blue medium loose", "blue medium tight"] 

Или без временных переменных:

arrays[0].product(*arrays[1..-1]).map { |s| s.join(' ') } 

Обратите внимание, что аргумент для product имеет префикс *. Это называется splat operator - он превращает массив в список аргументов.

0

Я думаю, что вы можете сделать это:

2.1.0 :001 > parent_array = [["red", "green", "blue"], ["small", "large", "medium"], ["loose", "tight"]] 
=> [["red", "green", "blue"], ["small", "large", "medium"], ["loose", "tight"]] 
2.1.0 :002 > first_array = parent_array.shift 
=> ["red", "green", "blue"] 
2.1.0 :003 > first_array 
=> ["red", "green", "blue"] 
2.1.0 :004 > parent_array 
=> [["small", "large", "medium"], ["loose", "tight"]] 

# Use the splat operator (*) 
2.1.0 :006 > product = first_array.product(*parent_array) 
=> [["red", "small", "loose"], ["red", "small", "tight"], ["red", "large", "loose"], ["red", "large", "tight"], ["red", "medium", "loose"], ["red", "medium", "tight"], ["green", "small", "loose"], ["green", "small", "tight"], ["green", "large", "loose"], ["green", "large", "tight"], ["green", "medium", "loose"], ["green", "medium", "tight"], ["blue", "small", "loose"], ["blue", "small", "tight"], ["blue", "large", "loose"], ["blue", "large", "tight"], ["blue", "medium", "loose"], ["blue", "medium", "tight"]] 
2.1.0 :007 > result = product.map {|array| array.join(' ') } 
=> ["red small loose", "red small tight", "red large loose", "red large tight", "red medium loose", "red medium tight", "green small loose", "green small tight", "green large loose", "green large tight", "green medium loose", "green medium tight", "blue small loose", "blue small tight", "blue large loose", "blue large tight", "blue medium loose", "blue medium tight"] 
0

Это одна из тех задач, для которых есть действительно только один хорошее решение, здесь один дается @Stefan. Тем не менее, это забавно, и, возможно, поучительно пытаться мечтать о других путях. Вот рекурсивный подход:

arr = [["red", "green", "blue"], 
     ["small", "large", "medium"], 
     ["loose", "tight"]] 

def combo(arr) 
    return arr.first.product(arr.last) if arr.size == 2 
    combo(arr[1..-1]).flat_map { |c| arr.first.map { |f| [f, *c] } } 
end 

combo(arr) 
    #=> [["red", "small", "loose"], ["green", "small", "loose"], 
    # ["blue", "small", "loose"], ["red", "small", "tight"], 
    # ["green", "small", "tight"], ["blue", "small", "tight"], 
    # ["red", "large", "loose"], ["green", "large", "loose"], 
    # ... 
    # ["green", "medium", "tight"], ["blue", "medium", "tight"]] 

Я предположил, что порядок элементов в массиве, возвращаемом не важно.

Смежные вопросы