在Javascript中,我试图采取数字值的初始数组,并计算其中的元素。理想情况下,结果将是两个新数组,第一个数组指定每个唯一元素,第二个数组包含每个元素出现的次数。但是,我愿意听取关于输出格式的建议。
例如,如果初始数组是:
5, 5, 5, 2, 2, 2, 2, 2, 9, 4
然后将创建两个新数组。第一个将包含每个唯一元素的名称:
5, 2, 9, 4
第二个将包含该元素在初始数组中出现的次数:
3, 5, 1, 1
因为数字5在初始数组中出现了三次,数字2出现了五次,9和4都出现了一次。
我一直在寻找解决方案,但似乎没有一个可行,而且我自己尝试过的每件事最后都出奇地复杂。任何帮助都将不胜感激!
谢谢:)
Const occurrence =[5,5,5,2,2,2,2,2,2,2,2,2,2,9,4]。Reduce(函数(acc, curr) {
返回acc[curr] ?++acc[curr]: acc[curr] = 1, acc
}, {});
Console.log (occurrences) // => {2: 5,4: 1,5: 3,9: 1}
这是一个经典的计算数组的方法。
var arr = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4];
var counted = [], count = [];
var i = 0, j = 0, k = 0;
while (k < arr.length) {
if (counted.indexOf(arr[k]) < 0) {
counted[i] = arr[k];
count[i] = 0;
for (j = 0; j < arr.length; j++) {
if (counted[i] == arr[j]) {
count[i]++;
}
}
i++;
} else {
k++;
}
}
如果您希望得到字母顺序的结果,可以先对其排序,但如果您希望保留输入数据的顺序,则可以尝试这种方法。嵌套循环可能比本页上的其他一些方法要慢一些。
使用O(n)时间复杂度的映射的解决方案。
var arr = [2, 2, 2, 2, 2, 4, 5, 5, 5, 9];
const countOccurrences = (arr) => {
const map = {};
for ( var i = 0; i < arr.length; i++ ) {
map[arr[i]] = ~~map[arr[i]] + 1;
}
return map;
}
演示:http://jsfiddle.net/simevidas/bnACW/
2021年的版本
更优雅的方法是使用逻辑空赋值(x ??= y)结合数组#reduce()与O(n)时间复杂度。
主要思想仍然是使用array# reduce()将输出作为对象进行聚合,以获得最高的性能(时间和空间复杂度),就像其他答案一样,搜索和构造中间数组。
Const arr = [2,2,2,2,2,2,4,5,5,5,9];
Const result = arr。Reduce ((acc, curr) => {
acc(咕咕叫)? ?= {[curr]: 0};
acc[咕咕叫][咕咕叫]+ +;
返回acc;
}, {});
console.log (Object.values(结果));
清理和重构代码
使用逗号操作符(,)语法。
逗号操作符(,)计算它的每个操作数(从左到右)
右)并返回最后一个操作数的值。
Const arr = [2,2,2,2,2,2,4,5,5,5,9];
Const result = arr。减少((acc,咕咕叫)= > (acc[咕咕叫]= (acc(咕咕叫)| | 0)+ 1,acc), {});
console.log(结果);
输出
{
"2": 5,
"4": 1,
"5": 3,
"9": 1
}
似乎问题特别要求有两个结果数组,我还没有看到,所以这是我的解决方案:
const theArray = [1, 3425, 56, 7, 9, 5, 4, 3425, 7, 7, 7];
const uniqueVals = [...new Set(theArray)];
const countPerUniqueValArray = uniqueVals.map(uv => theArray.filter(i => i === uv).length);
console.log(uniqueVals);
console.log(countPerUniqueValArray);
// Expect:
// [1, 3425, 56, 7, 9, 5, 4]
// [1, 2, 1, 4, 1, 1, 1]
ES6版本应该更简单(另一个一行解决方案)
let arr = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4];
let acc = arr.reduce((acc, val) => acc.set(val, 1 + (acc.get(val) || 0)), new Map());
console.log(acc);
// output: Map { 5 => 3, 2 => 5, 9 => 1, 4 => 1 }
Map代替普通对象帮助我们区分不同类型的元素,否则所有计数都是基于字符串