在Javascript中,我试图采取数字值的初始数组,并计算其中的元素。理想情况下,结果将是两个新数组,第一个数组指定每个唯一元素,第二个数组包含每个元素出现的次数。但是,我愿意听取关于输出格式的建议。

例如,如果初始数组是:

5, 5, 5, 2, 2, 2, 2, 2, 9, 4

然后将创建两个新数组。第一个将包含每个唯一元素的名称:

5, 2, 9, 4

第二个将包含该元素在初始数组中出现的次数:

3, 5, 1, 1

因为数字5在初始数组中出现了三次,数字2出现了五次,9和4都出现了一次。

我一直在寻找解决方案,但似乎没有一个可行,而且我自己尝试过的每件事最后都出奇地复杂。任何帮助都将不胜感激!

谢谢:)


当前回答

ECMAScript2015选项怎么样?

const a = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4];

const aCount = new Map([...new Set(a)].map(
    x => [x, a.filter(y => y === x).length]
));
aCount.get(5)  // 3
aCount.get(2)  // 5
aCount.get(9)  // 1
aCount.get(4)  // 1

这个例子将输入数组传递给Set构造函数,创建一个唯一值的集合。然后,扩展语法将这些值展开为一个新数组,这样我们就可以调用map并将其转换为一个[value, count]对的二维数组——即如下结构:

Array [
   [5, 3],
   [2, 5],
   [9, 1],
   [4, 1]
]

然后将新数组传递给Map构造函数,得到一个可迭代对象:

Map {
    5 => 3,
    2 => 5,
    9 => 1,
    4 => 1
}

Map对象的伟大之处在于它保留了数据类型——也就是说account .get(5)将返回3,但account .get("5")将返回未定义。它还允许任何值/类型作为键,这意味着该解决方案也适用于对象数组。

函数频率(/*{数组}*/ a){ 返回新地图([…]新组(a)] . map ( X => [X, a.filter(y => y == X).length] )); } 让foo = {value: 'foo'}, Bar = {value: ' Bar '}, Baz ={值:' Baz '}; let aNumbers = [5,5,5,2,2,2,2,2,2,2,2,9,4], aObjects = [foo, bar, foo, foo, baz, bar]; 频率(许多)。forEach (val关键)= > console.log(关键 + ': ' + val)); 频率(aObjects)。forEach((val, key) => console.log(key. log)Value + ': ' + val));

其他回答

使用MAP,您可以在输出中有两个数组:一个包含出现次数,另一个包含出现次数。

常量数据集=(2、2、4、2、6、4、7、8、5、6、7、10、10、10、15); Let values = []; Let keys = []; var mapwithoccurs = dataset.reduce((a,c) => { 如果(a.has (c)) a.set (c, a.get (c) + 1); 其他a.set (c, 1); 返回一个; }, new Map()) .forEach((value, key, map) => { keys.push(关键); values.push(价值); }); console.log(键) console.log(值)

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代替普通对象帮助我们区分不同类型的元素,否则所有计数都是基于字符串

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}

使用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/

给定下面提供的数组:

const array = [ 'a', 'b', 'b', 'c', 'c', 'c' ];

你可以使用这个简单的一行代码来生成一个哈希映射,将一个键链接到它在数组中出现的次数:

const hash = Object.fromEntries([ ...array.reduce((map, key) => map.set(key, (map.get(key) || 0) + 1), new Map()) ]);
// { a: 1, b: 2, c: 3 }

扩展和解释:

// first, we use reduce to generate a map with values and the amount of times they appear
const map = array.reduce((map, key) => map.set(key, (map.get(key) || 0) + 1), new Map())

// next, we spread this map into an array
const table = [ ...map ];

// finally, we use Object.fromEntries to generate an object based on this entry table
const result = Object.fromEntries(table);

这个数组归功于@corashina。减少代码