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

例如,如果初始数组是:

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

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

5, 2, 9, 4

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

3, 5, 1, 1

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

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

谢谢:)


当前回答

给定下面提供的数组:

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。减少代码

其他回答

我对拉姆达的解决方案:

const testArray = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4]

const counfFrequency = R.compose(
  R.map(R.length),
  R.groupBy(R.identity),
)

counfFrequency(testArray)

链接到REPL。

我认为这是最简单的方法如何计数发生在数组中相同的值。

var a = [true, false, false, false];
a.filter(function(value){
    return value === false;
}).length

您可以通过使用count函数扩展数组来简化这一点。它的工作原理类似于Ruby的array# count,如果你熟悉它的话。

Array.prototype.count = function(obj){
  var count = this.length;
  if(typeof(obj) !== "undefined"){
    var array = this.slice(0), count = 0; // clone array and reset count
    for(i = 0; i < array.length; i++){
      if(array[i] == obj){ count++ }
    }
  }
  return count;
}

用法:

let array = ['a', 'b', 'd', 'a', 'c'];
array.count('a'); // => 2
array.count('b'); // => 1
array.count('e'); // => 0
array.count(); // => 5

Gist


Edit

然后你可以使用array# filter获取你的第一个数组,包含每个出现的项:

let occurred = [];
array.filter(function(item) {
  if (!occurred.includes(item)) {
    occurred.push(item);
    return true;
  }
}); // => ["a", "b", "d", "c"]

你的第二个数组,使用数组#count到数组#map:

occurred.map(array.count.bind(array)); // => [2, 1, 1, 1]

或者,如果顺序无关紧要,你可以直接返回一个键值对:

let occurrences = {}
occurred.forEach(function(item) { occurrences[item] = array.count(item) });
occurences; // => {2: 5, 4: 1, 5: 3, 9: 1}

返回一个可排序的数组:

let array = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4] let reducedArray = array.reduce( (acc, curr, _, arr) => { if (acc.length == 0) acc.push({item: curr, count: 1}) else if (acc.findIndex(f => f.item === curr ) === -1) acc.push({item: curr, count: 1}) else ++acc[acc.findIndex(f => f.item === curr)].count return acc }, []); console.log(reducedArray.sort((a,b) => b.count - a.count )) /* Output: [ { "item": 2, "count": 5 }, { "item": 5, "count": 3 }, { "item": 9, "count": 1 }, { "item": 4, "count": 1 } ] */

你可以使用一个对象来保存结果:

Const arr = [5,5,5,2,2,2,2,2,2,2,2,9,4]; Const counts = {}; (const num of arr) { Counts [num] = Counts [num] ?计数[num] + 1: 1; } console.log(重要); Console.log(计数[5],计数[2],计数[9],计数[4]);

所以,现在你的counts对象可以告诉你一个特定数字的计数是多少:

console.log(counts[5]); // logs '3'

如果您想获取成员数组,只需使用keys()函数即可

keys(counts); // returns ["5", "2", "9", "4"]