如何获取数组的所有唯一元素,但保持最大重复次数

How to get all unique elements in for an array of array but keep max count of duplicates

本文关键字:元素 唯一 获取 何获取 数组      更新时间:2023-09-26

这个问题没有多大意义,但如果没有例子,就不知道如何用词。如果有人能把它写得更好,请随意编辑。

假设我有一个数组,比如:

[ ['a', 'a', 'b', 'c'], [], ['d', 'a'], ['b', 'b', 'b', 'e'] ]

我希望输出为:

 ['a', 'a', 'b', 'b', 'b', 'c', 'd', 'e']

不确定在javascript/jquery/aunderline中是否有简单的方法可以做到这一点。我可以想到的一种方法是查看这些数组中的每一个,计算每个元素出现的次数,并跟踪它出现的最大次数。然后我可以重新创建它。但考虑到我的数组可能很大,这似乎很慢。

您需要:

  • 循环遍历每个内部数组并计算值
  • 将每个值及其计数(如果高于当前计数)存储在计数器变量中
  • 最后,将值和计数转换为数组

下面的代码显示了该过程的大致轮廓。记住用适当的代码替换.forEachfor..in

var input = [['a', 'a', 'b', 'c'], [], ['d', 'a'], ['b', 'b', 'b', 'e']],
    inputCount = {};
input.forEach(function(inner) {
    var innerCount = {};
    inner.forEach(function(value) {
        innerCount[value] = innerCount[value] ? innerCount[value] + 1 : 1;
    });
    var value;
    for (value in innerCount) {
        inputCount[value] = inputCount[value] ? Math.max(inputCount[value], innerCount[value]) : innerCount[value];
    }
});
console.log(inputCount);
// Object {a: 2, b: 3, c: 1, d: 1, e: 1} 

经过一番折腾,我找到了一个解决方案,但不确定我是否足够喜欢它。如果我想不出其他的,我可能会用它。

我会使用underscorejs countBy来获取所有元素的计数。

var array = [ ['a', 'a', 'b', 'c'], [], ['d', 'a'], ['b', 'b', 'b', 'e'] ];
var count = _.map(array, function(inner) {
  return _.countBy(inner, function(element) {
    return element;
  });
});
var total = {};
_.each(_.uniq(_.flatten(array)), function(element) {
  var max = _.max(count, function(countedElement) {
    return countedElement[element];
  });
  total[element] = max[element];
});
console.log(total); // {a: 2, b: 3, c: 1, d: 1, e: 1} 

然后我会用这个总数重新创建数组。

以下是简单嵌套循环方法的示例:

var input = [ ['a', 'a', 'b', 'c'], [], ['d', 'a'], ['b', 'b', 'b', 'e'] ];
var countMap = {};
// iterate outer array
for (i=0; i < input.length; i++) {
    // iterate inner array
    for (j=0; j < input[i].length; j++) {
        // increment map counter
        var value = input[i][j];
        if (countMap[input[i][j]] === undefined) {
            countMap[value] = 1;
        } else {
            countMap[value]++;
        }
    }
}
console.log(countMap); // output such as {'a':2, 'b':4, 'c':1, 'd':1, 'e':1}

不是最有效的解决方案,但它应该描述您的过程:

var big = [ ['a', 'a', 'b', 'c'], [], ['d', 'a'], ['b', 'b', 'b', 'e'] ];
function map(arr){
    var map = {}
    for (var i=arr.length-1; i>-1; i--){
        if(arr[i] in map) map[arr[i]]++;
        else map[arr[i]] = 1;
    }
    return map;
}
function reduce(matrix){
    var arrMap = {};
    for (var i=matrix.length-1; i>-1; i--){
        var arrRes = map(matrix[i]);
        for (var key in arrRes){
            if( !arrMap[key] || arrMap[key] < arrRes[key])
                arrMap[key] = arrRes[key];
        }
    }
    return arrMap;
}
function calc(matrix){
    var res = [],
      arrMap = reduce(matrix);
    for (var key in arrMap){
        while(arrMap[key] > 0 ){
            res.push(key);
            arrMap[key]--;            
        }
    }
    return res;
}
console.log(calc(big));
// Array [ "e", "b", "b", "b", "a", "a", "d", "c" ]