2015-12-30 2 views
1

У меня есть этот код:У меня есть вопрос .. добавляющий

1 #!/local/usr/bin/ruby 
    2 
    3 users = (1..255).to_a 
    4 
    5 x = " " 
    6 y = " " 
    7 z = " " 
    8 #a = " " 
    9 
10 count = 1 
11 users.each do |i| 
12 x << i if count == 1 
13 y << i if count == 2 
14 z << i if count == 3 
15 # if x.length == 60 
16 # a << i if count == 1 
17 # a << i if count == 2 
18 # a << i if count == 3 
19 # else 
20 # end 
21 if count == 3 
22  count = 1 
23 else 
24  count += 1 
25 end 
26 end 
27 
28 puts x.length 
29 puts y.length 
30 puts z.length 
31 #puts a.length 
32 

Что делает этот код является добавление числа, 1-255 на три строки и выходы, сколько чисел в каждой строке.

РАБОТЫ

Пример рабочего кода:

[[email protected] ruby]$ ruby loadtest.rb 
86 
86 
86 
[[email protected] ruby]$ 

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

Когда я пытаюсь сделать это с закомментированного разделе выводит это:

[[email protected] ruby]$ ruby loadtest.rb 
86 
86 
86 
4 
[[email protected] ruby]$ ruby loadtest.rb 

ПОЧЕМУ ?! Что я делаю не так?

+0

Печать программы 86,86,86,4 не 86,86,86,256 –

+0

@WandMaker Да, я заметил, что я только что редактировал вопрос. – Bam

+0

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

ответ

1

... если каждая строка содержит 60 чисел Я хочу, чтобы добавить в строку до тех пор, пока не останется больше числа

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

x << i if count == 1 
    y << i if count == 2 
    z << i if count == 3 

так, что он прекращает добавление когда она попадает ваш предел.

Взглядами блока еще, что не делает ничего, я думаю, вы возглавляли в этом направлении:

if x.length == 60 
    a << i if count == 1 
    a << i if count == 2 
    a << i if count == 3 
    else 
    x << i if count == 1 
    y << i if count == 2 
    z << i if count == 3 
    end 

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

Я хотел бы предложить рефакторинг, чтобы сделать его чище:

users.each do |i| 
    target_string = case count 
    when 1 then x 
    when 2 then y 
    when 3 then z 
    end 

    target_string = a if target_string.length == 60 

    target_string << i 

    if count == 3 
    count = 1 
    else 
    count += 1 
    end 
end 
+0

OOOO это потрясающе, спасибо за отличную информацию! – Bam

1

Это может быть лучше использовать массив вместо строки, как вы подталкиваете числа в этих переменных.

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

x, y, z = r = Array.new(3) {[]} 
a = [] 

iter = [0,1,2].cycle 

(1..255).each do |i| 
    r.all? {|i| i.size == 60} ? a << i : r[iter.next] << i 
end 

p x.size, y.size, z.size 
p a.size 

Давайте определим наши массивы. Несмотря на то, что у меня есть массивы x, y и z, они присутствуют только потому, что они присутствуют в вашем коде - я думаю, нам просто нужны три массива, каждый из которых будет собирать числа, поскольку они выбираются из диапазона чисел - между 1 до 255 - один за другим. x,y,z = r использует метод параллельного присваивания и эквивалентен x,y,z = r[0],r[1],r[2]. Кроме того, использование Array.new(3) {[]} помогает в создании массива Array таким образом, что при доступе к r[1] он инициализируется пустым массивом ([]) по умолчанию.

x, y, z = r = Array.new(3) {[]} 
a = [] 

Для того, чтобы определить, какой массив следующий номер выбрал из диапазона должен быть помещен в, мы будем использовать перечислитель сгенерированный из Enumerable#cycle. Этот перечислитель особенный - потому что он является мягким бесконечным по своей природе, и мы можем продолжать просить его дать элемент, вызвав next, и он будет циклически перемещаться по элементам массива [0,1,2] - возвращая нас 0,1,2,0,1,2,0,1,2... бесконечно.

iter = [0,1,2].cycle 

Далее мы проведем итерацию по диапазону чисел 1..255. Во время каждой итерации мы проверим, имеют ли все 3 массива, в которых мы собираем номер, нужный размер 60 с помощью Enumerable#all? - если это так, мы добавим его в массив a - иначе мы назначим его одному из вспомогательные массивы r на основе индекса массива, возвращаемого счетчиком iter.

(1..255).each do |i| 
    r.all? {|i| i.size == 60} ? a << i : r[iter.next] << i 
end 

И наконец, мы печатаем размер каждого из массивов.

p x.size, y.size, z.size 
#=> 60, 60, 60 
p a.size 
#=> 75 
+0

Возможно, вы захотите объяснить, что делают 'cycle' и' next'. –

+0

@theTinMan Конечно, позвольте мне попытаться объяснить –

2

Что делает этот код добавляет число, 1-255 на три строки и выводит сколько чисел в каждой строке.

После уменьшения количества значений итерируемая для удобства чтения, вот что он делает:

users = (1..5).to_a 

x = " " 
y = " " 
z = " " 

count = 1 
users.each do |i| 
    x << i if count == 1 # => " \u0001", nil, nil, " \u0001\u0004", nil 
    y << i if count == 2 # => nil, " \u0002", nil, nil, " \u0002\u0005" 
    z << i if count == 3 # => nil, nil, " \u0003", nil, nil 

    if count == 3 
    count = 1 
    else 
    count += 1 
    end 
end 

x # => " \u0001\u0004" 
y # => " \u0002\u0005" 
z # => " \u0003" 

puts x.length 
puts y.length 
puts z.length 

# >> 3 
# >> 3 
# >> 2 

Ваш код создает двоичный файл внутри строки, а не «чисел», как мы обычно думаем о них, как цифры.

Продолжая, вы можете очистить свою логику, используя each_with_index и case/when. Для того, чтобы сделать результаты более читаемым я переключился от накопления в строки в массивы:

users = (1..5).to_a 

x = [] 
y = [] 
z = [] 

users.each_with_index do |i, count| 
    case count % 3 
    when 0 
    x << i 
    when 1 
    y << i 
    when 2 
    z << i 
    end 
end 

x # => [1, 4] 
y # => [2, 5] 
z # => [3] 

puts x.length 
puts y.length 
puts z.length 

# >> 2 
# >> 2 
# >> 1 

Реальный трюк в этом является использование %, который делает по модулю по значению.

+0

Почему он помещает 'nil' внутри строк вместо двоичного с 0001 - 0005 ...? – Bam

+0

Это не помещает ниль в строки. Посмотрите на значения для 'x',' y' и 'z'. –

+0

Awh получил ya. Ладно, спасибо, сэр. – Bam