2014-09-22 3 views
0

Учитывая массив длины N, как я могу равномерно распределять элементы массива в другой массив произвольной длины?Эффективный подход к распределению элементов массива в куски

Например, у меня есть 3 элемента в массиве, и я бы хотел, чтобы он распределялся равномерно по другому массиву из 9 слотов.

[1, 2, 3] 

должно привести (что-то близко к)

[[], [], [1], [], [], [2], [], [], [3]] 

Однако, если у меня есть 9 пунктов для распространения на длину массива 2, это должно привести к

[[1,2,3,4], [5,6,7,8,9]] 

Спасибо !

ПРИМЕЧАНИЕ: Позиция результирующих элементов массива может отличаться в соответствии с алгоритмом, но целью является получение некоторого уровня равномерного распределения. В первом примере 0-й элемент может быть [1]. Во втором примере 0-й элемент может иметь [1,2,3,4,5].

+0

Почему результат первого тестового примера положил 1 во 2-й индекс нового массива, а не в нуль? – Anthony

+0

Почему второй будет «[[1,2,3,4], [5,6,7,8,9]]», а не «[[1,2,3,4,5], [6, 7,8,9]] '? –

+0

Хорошие вопросы. Надеюсь, эта заметка прояснит это для вас. –

ответ

2

Вот простой способ сделать это:

def distribute(arr, slots) 
    n = arr.size 
    a = Array.new(slots) { [] } 
    arr.each_with_index { |e,i| a[i*slots/n] << e } 
    a 
end 

distribute([1,2,3], 9) 
    #=> [[1], [], [], [2], [], [], [3], [], []] 
distribute([*(1..9)], 2) 
    #=> [[1, 2, 3, 4, 5], [6, 7, 8, 9]] 

Вы можете изменить распределения, которые появляются в результате изменения i*slots/n.

1

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

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

Тестовые случаи:

it 'splits on n vals' do 
    arr = [1,2,3] 
    expect(chunk(arr, 9)).to eq [[], [], [1], [], [], [2], [], [], [3]] 
    end 

    it 'splits on n vals' do 
    arr = [1,2,3,4,5,6,7,8,9] 
    expect(chunk(arr,2)).to eq [[1,2,3,4,5],[6,7,8,9]] 
    end 

Код:

def chunk(arr, num) 
    if num < arr.length 
    return arr.each_slice((arr.size/num.to_f).round).to_a 
    end 
    array = [] 
    len = arr.length 
    (0..num).each do |i| 
    if (i % len == 0) && i != 0 
     array[i-1] = [arr.first] 
     array[i] = [] 
     arr.shift 
    else 
     array[i] = [] 
    end 
    end 
    array.pop 
    array 
end 
+0

Мне нравится, куда это направляется. Он решает для примеров в исходном вопросе, но не для других параметров. Например .. chunk ([1,2], 2) => [[], [1]]. Я подберу его. –

+0

Прохладный, можете ли вы пометить мой ответ, пожалуйста? – Anthony

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