用于分组元素和计算重复项的高效算法

时间:2016-12-16 08:18:31

标签: javascript jquery algorithm

我有一个对象数组。如果对象的一个​​属性与另一个对象相同,我认为它是重复的,我想通过此属性对对象进行分组,并存储有关“重复”发生次数的信息。

例如:

  

X A B O

     

Y X Z I

     

Y X Z U

     

X A B L

     

Y X Z K

我想按第一个值分组。另外两个属性在每个副本中也是相同的,但比较第一个值就足够了。我需要向用户显示如下结果:

  

Y X Z(3)

     

X A B(2)

我知道有一些算法,但我正在寻找一个有效的算法。有什么想法吗?

2 个答案:

答案 0 :(得分:0)

以下可能是一个选项。创建一个对象,该对象将代表每个属性的出现,如下所示:

{
  a: 1,
  b: 1,
  c: 2
  d: 4
}

给予这个对象你可以继续将事件分组,最后得到一个看似如下的对象:

{
  1: [ 'a', 'b' ],
  2: [ 'c' ],
  4: [ 'd' ]
}

这是一个例子,希望它有所帮助。



var data = [
  {x: 'x', a: 'a', b: 'b'},
  {y: 'y', x: 'x', z: 'z'},
  {y: 'y', x: 'x', z: 'z'},
  {x: 'x', c: 'c', b: 'b'}
];

function countOccurrence ( arr ) {
  var dubs = {};
  arr.forEach ( function ( item ) {
    Object.keys( item ).forEach ( function ( prop ) {
      ( dubs[prop] ) ? dubs[prop] += 1 : dubs[prop] = 1;
    });
  });
  return dubs;
}

function groupByOccurrence ( obj ) {
  return Object.keys ( obj ).reduce ( function ( a, b ) {
    ( a[obj[b]] ) ? a[obj[b]].push ( b ) : a[obj[b]] = [b];
    return a;
  }, {});
}

console.log ( groupByOccurrence ( countOccurrence ( data ) ) )

.as-console-wrapper { max-height: 100% !important; top: 0; }




答案 1 :(得分:0)

您可以使用树的组合并计算节点。



function iter(object, path) {
    var keys = Object.keys(object)

    if (keys.length === 1) {
        result.push(path.join('') + ' (' + object._ + ')');
        return;
    }
    keys.some(function (k) {
        if (k === '_') {
            return;
        }
        if (!path.length) {
            iter(object[k], path.concat(k));
            return;
        }
        if (object._ !== object[k]._) {
            result.push(path.join('') + ' (' + object._ + ')');
            return true;
        }
        iter(object[k], path.concat(k) );
    });
}

var data = [{ X: 1, A: 1, B: 1, O: 1 }, { Y: 1, X: 1, Z: 1, I: 1 }, { Y: 1, X: 1, Z: 1, U: 1 }, { X: 1, A: 1, B: 1, L: 1 }, { Y: 1, X: 1, Z: 1, K: 1 }, { i: 0, k: 0 }, { i: 0, k: 0 }],
    grouped = {},
    result = [];

data.forEach(function (o) {
    Object.keys(o).reduce(function (r, k) {
        r[k] = r[k] || {};
        r[k]._ = (r[k]._ || 0) + 1;
        return r[k];
    }, grouped);
});

iter(grouped, []);
console.log(result);

.as-console-wrapper { max-height: 100% !important; top: 0; }