2016-07-31 3 views
0

Дано число, мой код должен вернуть все четные числа между 1 и числом, и напечатать их в следующем формате:Рубиновые массивы методы и выходы

22 
4444 
666666 
etc... 

Это код до сих пор:

def pattern(n) 
    n == 1 ? "" : arr = (1..n).select {|i| i if i % 2 == 0}.each {|item| return (item.to_s * item)} 
end 

С любым номером больше четырех, он будет возвращать только следующее:

22 

Я думаю, что это может иметь какое-то отношение к return в блоке. Тем не менее, при использовании print или puts, это возвращает отдельный элемент массива следующим образом:

[2] 

Идеи для пути вокруг этого, так что можно достичь желаемых результатов?

+3

иногда лучше закодировать на несколько строк. –

ответ

2

Этот код исправляет проблему:

def pattern(n) 
    n == 1 ? "" : arr = (1..n).select {|i| i if i % 2 == 0}.map {|item| (item.to_s * item)} 
end 

Обратите внимание, что я использую map вместо each, и я не использую return. return означает, что вы на самом деле не закончили цикл по номерам ... как только вы добрались до 2, вы вернулись из функции.

map - это то, что вы хотите, если хотите создать новый массив с результатами.

EDIT

Побольше очистки:

def pattern(n) 
    n == 1 ? "" : (1..n).select {|i| i.even?}.map {|item| item.to_s * item} 
end 

arr = ненужно. Ваш блок в select должен просто вернуть true или false ... вы также можете использовать только i % 2 == 0, но even? существует. Кроме того, круглые скобки вокруг item.to_s * item не нужны.

EDIT 2

Per комментариев ниже, если вы хотите одну строки, может быть, это то, что вы ищете (добавлено .join("\n")):

def pattern(n) 
    n == 1 ? "" : (1..n).select {|i| i.even?}.map {|item| item.to_s * item}.join("\n") 
end 

EDIT 3

При возврате строки вы также можете пропустить специальный случай n==1, так как объединение пустого массива просто вернет пустую строку:

def pattern(n) 
    (1..n).select {|i| i.even?}.map {|item| item.to_s * item}.join("\n") 
end 
+0

Спасибо, это определенно помогло понять мои ошибки. Тем не менее, у меня все еще возникает проблема, что out puts выходит в следующем формате: ["22", "4444"]. Я попытался использовать каждый метод для нового сопоставленного массива для получения желаемого результата, но это тоже не помогло. – John

+0

Возможно, вам нужно что-то вроде 'pattern (8) .join (" \ n ")'? – smarx

+0

@John См. Мою последнюю редакцию. – smarx

2

Ваш код не работает, потому что он возвращается, когда он достигает первого значения. См:

def pattern n 
    return "" if n == 1 

    (1..n).select { |i| 
     i if i % 2 == 0 
    }.each { |item| 
     return (item.to_s * item) # You are returning here! 
    } 
end 

Как предложение, вы можете упростить ваш код:

def pattern n 
    (2..n).step(2) { |n| puts n.to_s * n } 
end 

или --Но лучше IMO-- вы возвращаете массив со всеми результатами, и пусть абонент решать, что делать с ним:

def pattern n 
    (2..n).step(2).map { |n| n.to_s * n } 
end 
+0

Спасибо, это, безусловно, гораздо более эффективное решение. Тем не менее, любое понимание того, почему мой код ведет себя так, как он есть? Я немного запутался в том, как он выводит значения. – John

+0

Вы всегда возвращаете первое сгенерированное значение, поэтому выход имеет значение «22». – Gabriel

+0

Кто-то проголосовал за мой ответ. Зачем? – Gabriel

0

Вот еще один способ, в котором вы можете решить эту проблему, используя Integer#times:

def pattern n 
    (2..n).each do |i| 
    next if i.odd?    
    i.times { print i } 
    puts 
    end 
end 

pattern 8 
#=> 
# 22 
# 4444 
# 666666 
# 88888888 
Смежные вопросы