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

例如,如果初始数组是:

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

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

5, 2, 9, 4

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

3, 5, 1, 1

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

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

谢谢:)


当前回答

查看下面的代码。

<html>
<head>
<script>
// array with values
var ar = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4];

var Unique = []; // we'll store a list of unique values in here
var Counts = []; // we'll store the number of occurances in here

for(var i in ar)
{
    var Index = ar[i];
    Unique[Index] = ar[i];
    if(typeof(Counts[Index])=='undefined')  
        Counts[Index]=1;
    else
        Counts[Index]++;
}

// remove empty items
Unique = Unique.filter(function(){ return true});
Counts = Counts.filter(function(){ return true});

alert(ar.join(','));
alert(Unique.join(','));
alert(Counts.join(','));

var a=[];

for(var i=0; i<Unique.length; i++)
{
    a.push(Unique[i] + ':' + Counts[i] + 'x');
}
alert(a.join(', '));

</script>
</head>
<body>

</body>
</html>

其他回答

使用ramda.js有一个更好更简单的方法可以做到这一点。 代码示例

Const ary = [5,5,5,2,2,2,2,2,2,2,2,2,9,4]; R.countBy (r = > r)(必要) countBy documentation是at documentation

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)

所以这里是我如何做的一些最新的javascript功能:

首先,将数组缩减为一个计数的Map:

let countMap = array.reduce(
  (map, value) => {map.set(value, (map.get(value) || 0) + 1); return map}, 
  new Map()
)

通过使用Map,您的起始数组可以包含任何类型的对象,并且计数将是正确的。如果没有Map,某些类型的对象会给你奇怪的计数。 关于区别的更多信息,请参阅Map文档。

如果你所有的值都是符号、数字或字符串,这也可以用在对象上:

let countObject = array.reduce(
  (map, value) => { map[value] = (map[value] || 0) + 1; return map },
  {}
)

或者使用解构和对象扩展语法,以一种没有突变的函数式方式略显花哨:

let countObject = array.reduce(
  (value, {[value]: count = 0, ...rest}) => ({ [value]: count + 1, ...rest }),
  {}
)

此时,您可以使用Map或对象进行计数(与对象不同,Map是直接可迭代的),或者将其转换为两个数组。

有关地图:

countMap.forEach((count, value) => console.log(`value: ${value}, count: ${count}`)

let values = countMap.keys()
let counts = countMap.values()

或者对于对象:

Object
  .entries(countObject) // convert to array of [key, valueAtKey] pairs
  .forEach(([value, count]) => console.log(`value: ${value}, count: ${count}`)

let values = Object.keys(countObject)
let counts = Object.values(countObject)

给定下面提供的数组:

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 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}