Руби каждый логический вопрос - PullRequest
6 голосов
/ 05 ноября 2010

Я пытаюсь решить простую задачу Ruby из Семь языков за семь недель

Распечатать содержимое массива шестнадцать чисел, четыре числа на время, используя только 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}

Ответы [ 8 ]

6 голосов
/ 05 ноября 2010

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

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

i = 0
a.each do |item|
  p a[i, 4] if(i % 4 == 0)
  i +=1
end
2 голосов
/ 22 сентября 2013

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

(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
1 голос
/ 05 ноября 2010

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

x = 4
(0...(a.size/x.to_f).ceil).each {|i| p a.slice(x*i,x)}
0 голосов
/ 08 апреля 2012

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

a.each {|i| p a[i,4] if (i+3) % 4 == 0}
0 голосов
/ 16 мая 2011

Вам запрещено использовать 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 голосов
/ 16 мая 2011

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

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 голосов
/ 05 ноября 2010

Проблема не состояла в том, что массив из шестнадцати чисел был последовательным или начинался с одного ... давайте создадим решение , которое работает для любых 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
0 голосов
/ 05 ноября 2010

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

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