2010-11-05 3 views
5

Я пытаюсь решить простую проблему Руби из Seven Languages in Seven Weeksрубин каждый логический вопрос

Печать содержимого массива шестнадцать номеров, четыре номера в время, используя только each

Вот что я придумал, можно ли это сделать простым способом или сделать его лучше?

a = (1..16).to_a 

i = 0 
j = [] 
a.each do |item| 
    i += 1 
    j << item 
    if(i % 4 == 0) 
    p j 
    j = [] 
    end 
end 

Это может сделать с помощью each_slice в одной строке

a.each_slice(4){|x| p x}

ответ

6

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

Я придумал решение ниже. Это та же идея, за исключением того, что она не использует aux var (j) для хранения частичных результатов.

i = 0 
a.each do |item| 
    p a[i, 4] if(i % 4 == 0) 
    i +=1 
end 
+0

Хороший. Только решение, не использующее переменную aux. Благодарю. –

+0

Проблема указала использование 'each', но не указала _which_ массив, на котором он должен был использоваться! –

0

Попробуйте это:

(1..16).each do |item| 
    print "#{item} " 
    print "\n" if item % 4 == 0 
end 
+0

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

0

Проблема не утверждала, что массив чисел шестнадцати был последовательным или начал в одном ... давайте создало решения, которое работает для любых 16 чисел.

########## 
# Method 1 - Store chunks of 4 and print at the end 
########## 
a = (1..16).to_a 
b = [] 
a.each do |item| 
    b << [] if b.size == 0 
    b << [] if b[-1].size == 4 
    b[-1] << item 
end 

# choose your desired printing method 
print b 
b.each{|c| puts c.join(",")} 

########## 
# Method 2 - print the chunks as they are encountered 
########## 

# Note: "p" was specifically chosen over "print" because it returns the value printed instead of nil. 
#  If you use a different printing function, make sure it returns a value otherwise the 'b' array will not clear. 


# Note: This implementation only prints out all array entries if a multiple of 4 
#  If 'b' contains any items outside the loop, they will not be printed 
a = (1..16).to_a 
b = [] 
a.each do |item| 
    b << item 
    b = [] if b.size == 4 and puts b 
end 


# Note: This implementation will print all array elements, even if number of elements is not multiple of 4. 
a = (1..16).to_a 
b = [] 
a.each do |item| 
    b = [] if b.size == 4 and p b 
    b << item 
end 
p b 
1

Я думаю, что это должно работать для любого массива размера и любой кусок размера х:

x = 4 
(0...(a.size/x.to_f).ceil).each {|i| p a.slice(x*i,x)} 
+0

Хороший тоже ... Мне тоже понравился этот подход .. –

0

я использовал что-то похожее на Мигеля, хотя его чище:

array = (1..16).to_a 
i = 0 
array.each do 
    puts array[i...i+4].to_s if i % 4 == 0 and i+4 <= array.size 
    i+=4 
end 
0

Вам запрещено использовать each_with_index? Если нет, основываясь на @ ответ Мигеля:

a.each_with_index do |item, i| 
    p a[i, 4] if i.modulo(4).zero? 
end 

я также заменил i % 4 == 0 с чем-то, что звучит как английский язык («я по модулю 4 равна нулю»)

0

Однострочные без среза:

a.each {|i| p a[i,4] if (i+3) % 4 == 0} 
2

Гленн Макдональдс короткий, но он использует срез, который не разрешен (только каждый, помните). Вот мой:

(0...a.size).each {|index| p a[index, 4] if index % 4 == 0} 

, который также хорошо работает для других размеров массивов, здесь применяются к 18 размеру массива:

>> a = (113..150).to_a.insert(5,55).insert(10,66666).shift(18) 
=> [113, 114, 115, 116, 117, 55, 118, 119, 120, 121, 66666, 122, 123, 124, 125, 126, 127, 128] 
>> (0...a.size).each {|index| p a[index, 4] if index % 4 == 0} 
[113, 114, 115, 116] 
[117, 55, 118, 119] 
[120, 121, 66666, 122] 
[123, 124, 125, 126] 
[127, 128] 
=> 0...18