如何对含type字段的数组按1:2:1的比例分配不同type类别的数据
数组按1:2:1比例分配实现方案
核心逻辑
- 第一步对原始数组按
type字段分组,得到三类数据的独立集合 - 第二步计算可支撑的最大比例基数k:因比例要求为1:2:1,k的取值受限于三类数据的实际存量,
k = Math.min(type1总数量, Math.floor(type2总数量/2), type3总数量),保证最终三类数据量为k、2k、k,严格符合比例要求 - 第三步从每类集合中截取对应数量的元素,组装为指定的输出结构
完整实现代码
// 原始数组 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分组 const groupByType = arr.reduce((res, item) => { if (!res[item.type]) res[item.type] = [] res[item.type].push(item) return res }, {1: [], 2: [], 3: []}) // 计算最大基数k const count1 = groupByType[1].length const count2 = groupByType[2].length const count3 = groupByType[3].length const k = Math.min(count1, Math.floor(count2 / 2), count3) // 组装结果 const lastArr = [ { type: 1, child: groupByType[1].slice(0, k) }, { type: 2, child: groupByType[2].slice(0, 2 * k) }, { type: 3, child: groupByType[3].slice(0, k) } ] console.log(lastArr)
可选调整
如果需要随机抽取元素而非按原始顺序取前N个,可以在截取前对分组后的数组做乱序处理,乱序参考代码:
// 数组乱序方法 function shuffle(array) { for (let i = array.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [array[i], array[j]] = [array[j], array[i]] } return array } // 使用示例:对type1分组乱序后再截取 child: shuffle(groupByType[1]).slice(0, k)
内容的提问来源于stack exchange,提问作者李大白白
相关产品推荐
相关产品推荐

