2016-08-10 2 views
3

Я новичок в программировании в Ruby и видел, что он имеет некоторые функциональные возможности. Интересно, есть ли способ сопоставления шаблонов на массивах; Я ищу, чтобы выполнить следующие действия:Соответствие шаблону массива Ruby

split_string = str.split("_", 2) 
fst = repo_branch_split.first 
snd = repo_branch_split.second 

в Haskell-подобным же образом:

[email protected](fst : snd) = str.split("_", 2) 

Есть ли что-нибудь подобное в рубин или нет?

+1

FYI это, как правило, (в языке-агностическом смысле), называемое деструктурирующим или деструктурирующим связыванием, а не совпадением с образцом. https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node252.html –

ответ

9

Это параллельное задание в Ruby. Вы можете задать массив переменных следующим образом:

fst, snd = str.split("_", 2) 

Вы также можете достичь головы/хвоста поведения от Haskell, назначая остальной части массива одной переменной:

head, *tail = "foo_bar_baz".split("_") 
# head => "foo" 
# tail => ["bar", "baz"] 

Без звезды в tail, он назначил бы только строку bar, а baz «исчезнет».

+5

Это единственный ответ на данный момент, который отвечает на вопрос, как он заявил, и проливает свет на разницу между «Параллельное назначение» и «сопоставление образцов». Кстати, фрагмент Haskell в OP не является примером соответствия шаблону в строгом смысле. – mudasobwa

+0

Это _is_ очень интересно. Теперь нам просто нужно поведение case/matching в Ruby. – Dogweather

2

Практически то же самое. Попробуйте

fst, snd = str.split("_", 2) 
1

@ ответ smefju является хорошо, но я просто разделить так, что вы можете сделать еще больше назначения деструктурирующих использования Рубите

def foo &f 
    # watch the array get destructured in the block below 
    f.call [1,2,3,4,5], :sweet, :candy 
end 

# first block param is array, so we can destructure it if you want 
foo do |(x,*xs),y,z| 
    puts %Q{ 
    x: #{x} 
    xs: #{xs} 
    y: #{y} 
    z: #{z} 
    } 
end 

Выхода

x: 1 
xs: [2, 3, 4, 5] 
y: sweet 
z: candy 

Это полезно всевозможными способами

hash = {a: 1, b: 2, c: 3} 
hash.reduce({}) do |acc,(k,v)| 
    puts %Q{ 
    acc: #{acc} 
    k: #{k} 
    v: #{v} 
    } 
    acc.merge(k => v * v) 
end 

Выход

acc: {} 
k: a 
v: 1 

acc: {:a=>1} 
k: b 
v: 2 

acc: {:a=>1, :b=>4} 
k: c 
v: 3 

=> {:a=>1, :b=>4, :c=>9} 

Помимо массивов Тхо уничтожение того, рубин очень не хватает в этом отделе. Вы не получите истинного хеш-деструктурирования, и нет такой вещи, как фактический шаблон соответствия в Ruby.

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