如何实现将一维数组元素索引按值分组至多维数组?
问题解决:将一维数组转换为按值存储索引的多维数组
需求确认
这个需求完全可行:给定存储0到n整数的一维数组data,生成多维数组result,其中result[n][x]存储数值n在data中第x+1次出现的索引。
示例输入:
var data = [ 2, 3, 4, 2, 5, 6, 8, 3, 6, 5, 1, 3, 5, 6, 1, 0, 6, 4, 2, 3, 4, 5, 6, 7, 1 ];
期望输出:
result = [ [15], [10, 14, 24], [0, 3, 18], [1, 7, 11, 19], [2, 17, 20], [4, 9, 12, 21], [5, 8, 13, 16, 22], [23], [6] ];
错误原因分析
你当前代码的问题有两个:
- 数组引用共享:
new Array(9).fill([])会把同一个空数组的引用填充到所有位置,导致所有result的元素指向同一个数组。每次push操作都会修改这个共享数组,最终所有位置的内容完全相同。 - 索引类型错误:
for...in遍历数组时,得到的i是字符串类型,会导致结果中存储的索引是字符串而非数字。
正确实现方法
方法1:手动初始化独立数组
先为result的每个位置创建独立的空数组,再遍历data记录索引:
var data = [ 2, 3, 4, 2, 5, 6, 8, 3, 6, 5, 1, 3, 5, 6, 1, 0, 6, 4, 2, 3, 4, 5, 6, 7, 1 ]; // 初始化每个位置为独立空数组 var result = new Array(9); for (let i = 0; i < result.length; i++) { result[i] = []; } // 遍历data,记录每个数值的索引 for (let i = 0; i < data.length; i++) { result[data[i]].push(i); } console.log(result);
方法2:使用reduce简化实现
利用reduce方法自动处理数组初始化,无需提前知道数组长度(如果不确定最大数值n时更灵活):
var data = [ 2, 3, 4, 2, 5, 6, 8, 3, 6, 5, 1, 3, 5, 6, 1, 0, 6, 4, 2, 3, 4, 5, 6, 7, 1 ]; // 用reduce构建结果数组 var result = data.reduce((acc, val, idx) => { // 如果当前数值对应的数组未初始化,创建新数组 if (!acc[val]) { acc[val] = []; } acc[val].push(idx); return acc; }, []); // 补全到需要的长度(比如0到8共9个元素),避免缺失值的位置为undefined const maxNum = 8; for (let i = 0; i <= maxNum; i++) { if (!result[i]) { result[i] = []; } } console.log(result);
方法3:使用forEach遍历
更简洁的遍历方式,同样保证索引为数字类型:
var data = [ 2, 3, 4, 2, 5, 6, 8, 3, 6, 5, 1, 3, 5, 6, 1, 0, 6, 4, 2, 3, 4, 5, 6, 7, 1 ]; var result = new Array(9).fill().map(() => []); // 用map生成独立数组 data.forEach((val, idx) => { result[val].push(idx); }); console.log(result);
内容的提问来源于stack exchange,提问作者shizuku3158
相关产品推荐
相关产品推荐

