Как на 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: {A:'A'}
1: {B:'B'}
..
Пора этот сборный объект записать в результат когда следующим, i+1 индексом, будет кратный длине отрезка, т.е. дающий 0 в остатке от деления. И тогда же, после записи, надо «обнулить» сборный объект для следующей пачки.
Наконец, при выходе из цикла, если в объекте что-то записано, надо этот неполный объект тоже не забыть записать в результат.
Комментариев нет:
Отправить комментарий