Страницы

Поиск по вопросам

суббота, 13 октября 2018 г.

Javascript: разбить массив на n-ое количество частей

Как на JavaScript можно разбить массив на не более, чем 5 частей в случае разного состава объектов в массиве?
Например, из:
a= [{A:'A'}, {B:'B'}, {C:'C'}, {D:'D'}, {E:'E'}, {F:'F'}, {G:'G'}, {H:'H'}, {I:'I'}];
Получить:
b= [{a:{A:'A'}, b:{B:'B'}}, {c:{C:'C'}, d:{D:'D'}}, {e:{E:'E'}, f:{F:'F'}}, {g:{G:'G'}, h:{H:'H'}}, {i:{I:'I'}}];
P.s. Спасибо за ответы!


Ответ

«Правильный» вариант с reduce() – ведь формально мы из массива получаем какое-то одно значение. Тоже массив, в данном случае.
var a = [{A:'A'}, {B:'B'}, {C:'C'}, {D:'D'}, {E:'E'}, {F:'F'}, {G:'G'}, {H:'H'}, {I:'I'}]; function splitTo( arr, n) { var plen = Math.ceil(arr.length / n); return arr.reduce( function( p, c, i, a) { if(i%plen === 0) p.push({}); p[p.length-1][i] = c; return p; }, []); } var result = splitTo( a, 3); document.body.innerText = JSON.stringify(result);
Нужно знать длину отрезка – округлением в бОльшую сторону деления длины на число отрезков.
Метод массива .reduce() применяет к каждому элементу ф-ю, переданную 1-м параметром, и возвращает одно значение. 2-м параметром даётся начальное значение. Ф-я принимает 4 параметра:
«текущее» значение – сначала оно берётся из «начального значения», а потом оно – то, что вернул предыдущий запуск этой ф-ии с предыдущим элементом массива; очередной элемент из массива; индекс очередного элемента; весь массив, на всякий случай.
Внутри поступаем просто. Если индекс делится на длину отрезка без остатка, то пора дописать в результат пустой объект.
И в любом случае в последний элемент результата дописываем ключём – индекс, а значением очередной элемент массива. Прелесть в том, что не нужно проверять какие-то условия, осталось ли что-то в «хвосте» и т.п. Красота!

Первоначальный вариант ответа, принятый ТС:
Чтобы разделить на 5 (пусть, переменная, parts) частей, надо вычислить, какой длины должны быть части:
len = Math.ceil( a.length / parts); // округлить в бОльшую сторону
И потом идём по элементам, набирая по len элементов, пока не закончатся:
var a = [{A:'A'}, {B:'B'}, {C:'C'}, {D:'D'}, {E:'E'}, {F:'F'}, {G:'G'}, {H:'H'}, {I:'I'}]; var parts = 5; // сколько частей var len = Math.ceil( a.length / parts) ,out = [] ,obj = {} ,i ; for( i=0; i Считаем элементы исходного массива от 0. В объект-заготовку записываем свойством индекс, а значением – очередной элемент исх. массива:
0: {A:'A'} 1: {B:'B'} ..
Пора этот сборный объект записать в результат когда следующим, i+1 индексом, будет кратный длине отрезка, т.е. дающий 0 в остатке от деления. И тогда же, после записи, надо «обнулить» сборный объект для следующей пачки.
Наконец, при выходе из цикла, если в объекте что-то записано, надо этот неполный объект тоже не забыть записать в результат.

Комментариев нет:

Отправить комментарий