如何为数组元素按首次出现顺序分配对应序号?
解决方法
基于你现有代码的快速改造
你已经拿到了去重后的数组 arr1_uniq,其实不需要单独维护序号数组,直接用map方法结合indexOf就能生成目标结果:
function onlyUnique(value, index, array) { return array.indexOf(value) === index; } let arr1 = ['a', 'a', 'b', 'c', 'a' ]; var arr1_uniq= arr1.filter(onlyUnique); // 新增这一行,直接映射原数组到对应的编号 let result = arr1.map(item => arr1_uniq.indexOf(item)); console.log(result); // 输出 [0, 0, 1, 2, 0]
indexOf会返回元素在arr1_uniq中首次出现的索引,正好对应你要的编号。
更高效的优化方案
上面的方法虽然简单,但如果原数组很大,indexOf每次都要遍历去重数组,效率会偏低。可以用一个对象来存储元素和编号的映射关系,时间复杂度降到O(n):
let arr1 = ['a', 'a', 'b', 'c', 'a']; const elementMap = {}; let currentNumber = 0; // 先遍历一次数组,给首次出现的元素分配编号 arr1.forEach(item => { if (!elementMap.hasOwnProperty(item)) { elementMap[item] = currentNumber++; } }); // 生成结果数组 const result = arr1.map(item => elementMap[item]); console.log(result); // 输出 [0, 0, 1, 2, 0]
这个方案只需要两次遍历数组,比前者更高效,也更简洁,不需要单独写去重函数。
关于你提到的findIndex问题
如果你之前尝试用findIndex,正确写法应该是这样的:
let result = arr1.map(item => arr1_uniq.findIndex(el => el === item));
和indexOf效果一致,但indexOf专门用于查找元素的索引,写法更简洁。如果之前出错,大概率是findIndex的回调函数写得有问题,比如没有正确判断元素相等。
内容的提问来源于stack exchange,提问作者nbs335
相关产品推荐
相关产品推荐

