JavaScript -查找数组中最常见的数字,即使有两个

moiiocjp  于 2023-03-21  发布在  Java
关注(0)|答案(5)|浏览(145)

如果我有一个数字数组,我想得到一个出现最频繁的,但有两个可能的答案,我有麻烦排序的一部分。例如,下面应该返回1和7,但我只得到7。任何帮助是感激。

let arr = [1, 1, 2, 3, 4, 5, 6, 7, 7];

function findMode(numbers) {
    let counted = numbers.reduce((acc, curr) => { 
        if (curr in acc) {
            acc[curr]++;
        } else {
            acc[curr] = 1;
        }

        return acc;
    }, {});

    let mode = Object.keys(counted).reduce((a, b) => counted[a] > counted[b] ? a : b);

    return mode;
}

console.log(findMode(arr));
vfhzx4xs

vfhzx4xs1#

你可以将相等的元素分组到子数组中,然后按子数组长度排序,并检索具有相同数组长度的第一个值,如下所示:

const arr = [1, 1, 2, 3, 4, 5, 6, 7, 7],
  output = arr
    .sort((a, b) => a - b)
    .reduce(
      (acc, cur, i, { [i - 1]: last }) =>
        (cur === last ? acc[acc.length - 1].push(cur) : acc.push([cur])) && acc,
      []
    )
    .sort((a, b) => b.length - a.length)
    .reduce(
      (a, b, _, [first]) => (first.length === b.length ? [...a, b[0]] : a),
      []
    );

console.log(output);
7xllpg7q

7xllpg7q2#

可以使用数组作为累加器。

let arr = [1, 1, 2, 3, 4, 5, 6, 7, 7];

function findMode(numbers) {
    let counted = numbers.reduce((acc, curr) => { 
        if (curr in acc) {
            acc[curr]++;
        } else {
            acc[curr] = 1;
        }

        return acc;
    }, {});

    let mode = Object.keys(counted).reduce((acc, curr) => {
      if(!acc.length || counted[curr] > counted[acc[0]]) return [curr];
      if(counted[curr] === counted[acc[0]]) acc.push(curr);
      return acc;
    }, []);

    return mode;
}
console.log(findMode(arr));

或者,您可以找到最高频率,然后使用filter查找具有该频率的数字。

let arr = [1, 1, 2, 3, 4, 5, 6, 7, 7];

function findMode(numbers) {
    let counted = numbers.reduce((acc, curr) => { 
        if (curr in acc) {
            acc[curr]++;
        } else {
            acc[curr] = 1;
        }
        return acc;
    }, {});
    let mode = Math.max(...Object.values(counted));
    return Object.keys(counted).filter(x => counted[x] === mode);
}
console.log(findMode(arr));
8zzbczxx

8zzbczxx3#

你可以在第一次循环中跟踪max的出现次数,然后使用Array#filter来获得具有以下值的keys

function findMode(numbers) {
    let max = 0;
    const counted = numbers.reduce((acc, curr) => { 
        if (curr in acc) acc[curr]++;
        else acc[curr] = 1;
        if(acc[curr] > max) max = acc[curr];
        return acc;
    }, {});
    const mode = Object.keys(counted)
      .filter(key => counted[key] === max)
      .map(Number);
    return mode;
}

console.log( findMode([1, 1, 2, 3, 4, 5, 6, 7, 7]) );
oxalkeyp

oxalkeyp4#

由于整个操作发生在函数作用域内,我们也可以用两个.forEach()循环来完成:在第一个中,我们收集计数,然后在第二个中,我们用“获胜者”组装结果数组。
通过使用map来收集计数,我们避免了使用普通对象时会发生的类型转换为字符串。

let arr = [1, 1, 2, "1", 3, 4, "1", 5, 6, 7, 7];

function findMode(nums) {
  let cn=new Map(),mx=0,res;
  nums.forEach(n=>cn.set(n,(cn.get(n)||0)+1));
  [...cn.entries()].forEach(([v,c])=>{
   if(c>mx) {res=[v];mx=c}
   else if (c===mx) res.push(v) });
  return res;
}
console.log(findMode(arr));
n6lpvg4x

n6lpvg4x5#

你可以通过在一个循环中直接获取count,max frequency和values来减少数组。

function findMode(numbers) {
    return numbers
        .reduce((r, v) => { 
            r[v] = (r[v] || 0) + 1;
            if (r[v] === r.max) r.values.push(v);
            if (r[v] > r.max) {
                r.max = r[v];
                r.values = [v];
            }
            return r;
        }, { max: 0, values: [] })
        .values;
}

console.log(findMode([1, 1, 2, 3, 4, 5, 6, 7, 7]));

相关问题