查找数组中重复项最少的项目

时间:2017-03-09 18:39:45

标签: javascript node.js

好的,因为标题说我的目标是找到最少的重复元素,因为元素只是整数。

ex1: array = [1,1,2,2,3,3,3]结果应为1,2

ex2: array = [1,2,2,3,3,4]结果应为1,4

我可以使用xor运算符来查找只出现一次的元素,但因为可能只有重复,所以我不能。

我正在考虑首先检查XOR是否包含任何非重复元素。如果没有继续使用for来检查相同元素的两次出现,依此类推,但这不是一个好方法,因为它有点慢,

有什么建议吗?

3 个答案:

答案 0 :(得分:0)

可能有更好或更快的解决方案,但我建议创建一个哈希(对象),其中整数为键,计数为值。您可以在数组的一个循环中创建它。然后,遍历对象键,跟踪找到的最小值,如果满足最小重复值,则将键添加到结果数组中。

示例实施:

const counts = input.reduce((counts, num) => {
    if (!counts.hasOwnProperty(num)) {
        counts[num] = 1;
    }
    else {
        counts[num]++;
    }
    return counts;
}, {});

let minimums = [];
let minCount = null;
for (const key in counts) {
    if (!minimums.length || counts[key] < minCount) {
        minimums = [+key];
        minCount = counts[key];
    }
    else if (counts[key] === minCount) {
        minimums.push(+key);
    }
}

return minimums;

您还可以使用lodash进行一些简化:一次操作获取计数,另一次获取最小计数,并获取与该最小计数匹配的值列表作为键:

import { countBy, invertBy, min, values } from "lodash";

const counts = countBy(input);
const minCount = min(values(counts));

return invertBy(counts)[minCount];

答案 1 :(得分:0)

您可以计算外观,按计数排序并删除所有相同的最大计数键。然后返回原始值。

步骤:

  • 声明所有变量,特别是没有任何原型的哈希对象,
  • 使用项目作为键得到哈希表,如果没有设置使用具有原始值和计数属性的对象,
  • 增加实际哈希的数量,
  • 从哈希表中获取所有密钥
  • 按计数的降序排列键,
  • 获取第一个元素的计数并将其存储在min
  • 使用min次数
  • 过滤所有密钥
  • 获取所有剩余密钥的原始值。

function getLeastDuplicateItems(array) {
    var hash = Object.create(null), keys, min;
    array.forEach(function (a) {
        hash[a] = hash[a] || { value: a, count: 0 };
        hash[a].count++;
    });
    keys = Object.keys(hash);
    keys.sort(function (a, b) { return hash[a].count - hash[b].count; });
    min = hash[keys[0]].count;
    return keys.
        filter(function (k) {
            return hash[k].count === min;
        }).
        map(function (k) {
           return hash[k].value;
        });
}

var data = [
        [1, 1, 2, 2, 3, 3, 3],
        [1, 2, 2, 3, 3, 4],
        [4, 4, 4, 6, 6, 4, 7, 8, 5, 5, 6, 3, 4, 6, 6, 7, 7, 8, 3, 3]
    ];

console.log(data.map(getLeastDuplicateItems));
.as-console-wrapper { max-height: 100% !important; top: 0; }

单循环解决方案,其中包含min的变量和用于收集计数的数组。

function getLeastDuplicateItems(array) {
    var hash = Object.create(null),
        temp = [],
        min = 1;

    array.forEach(function (a) {
        var p = (temp[hash[a]] || []).indexOf(a);
        hash[a] = (hash[a] || 0) + 1;
        temp[hash[a]] = temp[hash[a]] || [];
        temp[hash[a]].push(a);
        if (min > hash[a]) {
            min = hash[a];
        }
        if (p === -1) {
            return;
        }
        temp[hash[a] - 1].splice(p, 1);
        if (min === hash[a] - 1 && temp[hash[a] - 1].length === 0) {
            min++;
        }
    }, []);
    return temp[min];
}

var data = [
        [1, 1, 2, 2, 3, 3, 3],
        [1, 2, 2, 3, 3, 4],
        [4, 4, 4, 6, 6, 4, 7, 8, 5, 5, 6, 3, 4, 6, 6, 7, 7, 8, 3, 3],
    ];

console.log(data.map(getLeastDuplicateItems));
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 2 :(得分:0)

使用new Set()和少量Array.prototype函数的另一种方法。如果您有任何疑问,请与我们联系。

&#13;
&#13;
var array1 = [1, 1, 2, 2, 3, 3, 3],
    array2 = [1, 2, 2, 3, 3, 4];

function sort(arr) {
  var filtered = [...new Set(arr)],
      solution = [],
      res = filtered.reduce(function(s, a) {
        s.push(arr.filter(c => c == a).length);
        return s;
      }, []);

  var minDupe = Math.min.apply([], res);
  res.forEach((v, i) => v == minDupe ? solution.push(filtered[i]) : null)
  console.log(solution)
}

sort(array1);
sort(array2);
&#13;
&#13;
&#13;

使用Array#forEach代替Array#reduce

&#13;
&#13;
var array1 = [1, 1, 2, 2, 3, 3, 3],
    array2 = [1, 2, 2, 3, 3, 4];

function sort(arr) {
  var filtered = [...new Set(arr)],
      solution = [],
      res = [];
      filtered.forEach(v => res.push(arr.filter(c => c == v).length));
      
  var minDupe = Math.min.apply([], res);
  res.forEach((v, i) => v == minDupe ? solution.push(filtered[i]) : null)
  console.log(solution)
}

sort(array1);
sort(array2);
&#13;
&#13;
&#13;