2016-12-16 69 views
1

我有一個對象數組。如果對象的一個​​屬性與另一個對象相同,我認爲它是重複的,我想通過此屬性對對象進行分組,並存儲有關「重複」發生次數的信息。分組元素和計數重複的高效算法

例如:

X A B○

Y X Z I

Y X Zü

X A B1中

Y X Zķ

我想按第一個值分組。另外兩個屬性在每個副本中也是相同的,但比較第一個值就足夠了。我需要顯示給用戶的結果,看起來像:

YXZ(3)

XAB(2)

我知道有一些算法,但我期待爲一個有效的。有任何想法嗎?

+3

我建議你揭露你在談論第一算法,並告訴我們爲什麼它的效率不高,足以讓你的需要。你真的嘗試過嗎? –

+0

假設* property *可以轉換爲一個有效的標識符,那麼只需要一次通過數組。無論如何不會變得更好。 – Yoshi

+0

你是否考慮使用Lodash?有一個['groupBy'](https://lodash.com/docs/4.17.2#groupBy)函數。 –

回答

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; }

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; }