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

例如,如果初始数组是:

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

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

5, 2, 9, 4

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

3, 5, 1, 1

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

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

谢谢:)


当前回答

Const arr = [2,2,5,2,2,2,4,5,5,9]; 函数foo(数组){ Let a = [], B = [], Arr =…, //克隆数组,这样我们在使用.sort()时不会改变原始数组 prev; arr.sort (); For (let元素的arr) { If (element !== prev) { a.push(元素); b.push (1); } + + b (b。长度- 1]; Prev =元素; } 返回[a, b]; } Const result = foo(arr); console.log('(' +结果[0 ] + ']','[' + 结果[1]+ ')') console.log (arr)

其他回答

如果使用下划线或lodash,这是最简单的事情:

_.countBy(array);

这样:

_.countBy([5, 5, 5, 2, 2, 2, 2, 2, 9, 4])
=> Object {2: 5, 4: 1, 5: 3, 9: 1}

正如其他人指出的那样,然后可以对结果执行_.keys()和_.values()函数,以分别获得唯一的数字及其出现次数。但根据我的经验,原始对象更容易处理。

您可以通过使用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}

我对拉姆达的解决方案:

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。

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

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