tengo una matriz
let arr = [ { type: 1, title: 1 }, { type: 1, title: 1 }, { type: 2, title: 1 }, { type: 2, title: 1 }, { type: 2, title: 1 }, { type: 2, title: 1 }, { type: 2, title: 1 }, { type: 3, title: 1 }, { type: 3, title: 1 }, { type: 3, title: 1 }, { type: 3, title: 1 }, { type: 3, title: 1 }, { type: 3, title: 1 }, { type: 3, title: 1 }, { type: 3, title: 1 }, { type: 3, title: 1 }, { type: 3, title: 1 }, { type: 1, title: 1 }, { type: 1, title: 1 }, { type: 3, title: 1 }, { type: 3, title: 1 }, { type: 3, title: 1 }, { type: 1, title: 1 }, { type: 1, title: 1 }, { type: 3, title: 1 }, { type: 3, title: 1 }, { type: 1, title: 1 }, { type: 1, title: 1 }]
Quiero datos = 1(tipo==1):2(tipo==2):1tipo==1(3) (5:10:5)
Puede haber muchos datos, pero no importa cuántos datos haya, solo espero finalmente obtener datos 1: 2: 1. Quiero el último resultado, por ejemplo.
last arr = [ { type: 1, child: [{ type: 1, title: 1 },{ type: 1, title: 1 },{ type: 1, title: 1 },{ type: 1, title: 1 },{ type: 1, title: 1 }] }, { type: 2, child: [{ type: 2, title: 1 },{ type: 2, title: 1 },{ type: 2, title: 1 },{ type: 2, title: 1 },{ type: 2, title: 1 },{ type: 2, title: 1 },{ type: 2, title: 1 },{ type: 2, title: 1 },{ type: 2, title: 1 },{ type: 2, title: 1 }] }, { type: 3, child: [{ type: 3, title: 1 },{ type: 3, title: 1 },{ type: 3, title: 1 },{ type: 3, title: 1 },{ type: 3, title: 1 }] } ]
Para obtener la salida deseada, en la proporción deseada, podemos hacer un bucle, agregando la proporción correcta de elementos a la salida, desde la matriz de entrada, hasta que no sea posible agregar más, o hayamos alcanzado el conteo máximo (en este caso 20 ).
Por ejemplo, si la relación es 1:2:1, agregamos 1,2,1 elementos de cada tipo para cada iteración, deteniéndonos si
Creamos una función takeNItems()
que elimina N elementos de un determinado tipo de una matriz y los devuelve en otra matriz.
let arr = [ { type: 1, title: 1 }, { type: 1, title: 1 }, { type: 2, title: 1 }, { type: 2, title: 1 }, { type: 2, title: 1 }, { type: 2, title: 1 }, { type: 2, title: 1 }, { type: 3, title: 1 }, { type: 3, title: 1 }, { type: 3, title: 1 }, { type: 3, title: 1 }, { type: 3, title: 1 }, { type: 3, title: 1 }, { type: 3, title: 1 }, { type: 3, title: 1 }, { type: 3, title: 1 }, { type: 3, title: 1 }, { type: 1, title: 1 }, { type: 1, title: 1 }, { type: 3, title: 1 }, { type: 3, title: 1 }, { type: 3, title: 1 }, { type: 1, title: 1 }, { type: 1, title: 1 }, { type: 3, title: 1 }, { type: 3, title: 1 }, { type: 1, title: 1 }, { type: 1, title: 1 }, { type: 2, title: 1 }, { type: 2, title: 1 }, { type: 2, title: 1 }, { type: 2, title: 1 }, { type: 2, title: 1 }, ] // The ratios by type const ratios = { 1: 1, 2: 2, 3: 1 }; const totalCount = 20; function takeNItems(arr, type, count) { let result = []; do { let index = arr.findIndex(item => item.type === type); if (index === -1) return null; result.push(...arr.splice(index, 1)) } while (result.length < count) return result; } let count = 0; let roundCount = Object.values(ratios).reduce((sum, n) => sum + n,0); let result = Object.keys(ratios).map(type => ({ type: +type, count: 0, child: [] })); do { let nextRound = result.map(({type}, i) => takeNItems(arr, type, ratios[type])); // Not enough items for another round... if (nextRound.flat().length < roundCount) break; nextRound.forEach((items, i) => { result[i].count += items.length; result[i].child.push(...items); }); count += nextRound.flat().length; } while (count < totalCount); console.log('Result:', result)
.as-console-wrapper { max-height: 100% !important; top: 0; }