如何在不改变任何内容的情况下找到数组中出现频率最高的项目?



我想知道如何在不使用不可变.js的情况下,在纯javascript的不可变实现中重构此代码。

var arr1=[3, 'oo', 'oo', 'oo', 2, 3, 'oo', 3, 'oo', 2, 4, 9, 3];
var mf = 1;
var m = 0;
var item;
for (var i=0; i<arr1.length; i++)
{
for (var j=i; j<arr1.length; j++)
{
if (arr1[i] == arr1[j])
m++;
if (mf<m)
{
mf=m; 
item = arr1[i];
}
}
m=0;
}
console.log(item+" ( " +mf +" times ) ");

看起来您正在尝试查找数组中出现频率最高的项目。用reduce计算每个元素的重复次数,并找到最大重复次数。

在减少时,请确保每次都为累加器返回一个新对象,以免发生变异。

const arr1 = [3, 'oo', 'oo', 'oo', 2, 3, 'oo', 3, 'oo', 2, 4, 9, 3];
const reps = arr1.reduce((accum, item) => {
const newCount = (accum[item] || 0) + 1;
return { ...accum, [item]: newCount };
}, {});
const maxTimes = Math.max.apply(null, Object.values(reps));
const [recordItem] = Object.entries(reps).find(([, val]) => val === maxTimes);
console.log(recordItem + " ( " + maxTimes +" times ) ");

如果需要标识与记录匹配的所有项目,请使用filter而不是find

const arr1 = [3, 'oo', 'oo', 'oo', 2, 3, 'oo', 3, 'oo', 2, 4, 9, 3, 3];
const reps = arr1.reduce((accum, item) => {
const newCount = (accum[item] || 0) + 1;
return { ...accum, [item]: newCount };
}, {});
const maxTimes = Math.max.apply(null, Object.values(reps));
const recordItems = Object.entries(reps)
.filter(([, val]) => val === maxTimes)
.map(([key, val]) => key);
console.log(recordItems.join(', ') + " ( " + maxTimes +" times ) ");

使用Map().reduce(),您可以创建一个非常实用的方法:

const array = [3, 'oo', 'oo', 'oo', 2, 3, 'oo', 3, 'oo', 2, 4, 9, 3]
const maxOccurences = array => Array.from(
array.reduce(
(map, value) => map.set(
value,
map.has(value)
? map.get(value) + 1
: 1
),
new Map()
).entries()
).reduce(
(max, entry) => entry[1] > max[1] ? entry : max
).reduce(
(item, count) => ({ item, count })
)
console.log(maxOccurences(array))

并不是说我建议在生产代码中这样做,但为了方便起见,您可以修改Array.prototype以将此功能扩展为数组的成员方法:

const array = [3, 'oo', 'oo', 'oo', 2, 3, 'oo', 3, 'oo', 2, 4, 9, 3]
Object.defineProperty(Array.prototype, 'max', {
value () {
return Array.from(
this.reduce(
(map, value) => map.set(
value,
map.has(value)
? map.get(value) + 1
: 1
),
new Map()
).entries()
).reduce(
(max, entry) => entry[1] > max[1] ? entry : max
).reduce(
(item, count) => ({ item, count })
)
},
configurable: true,
writable: true
})
console.log(array.max())

最新更新