2014-06-20 44 views
1

我有對象的數組:過濾器獨特的和重複的對象

data = [{"origin":"SJU","dest":"JFK","rank":48},{"origin":"JFK","dest":"SJU","rank":21},{"origin":"IAD","dest":"LAX","rank":31},{"origin":"LAS","dest":"SJU","rank":21}] 

我試圖提取所有複製&唯一對象BY「出身」 &「目標」。因此,這2是相同的,忽略了排名鍵

  • {origin:'JFK',dest:'SJU',rank:21}
  • {"origin":"SJU","dest":"JFK","rank":48}

基本上我想要2個獨立的陣列:

duplicates=[{"origin":"SJU","dest":"JFK","rank":48},{"origin":"JFK","dest":"SJU","rank":21}]

unique = [{"origin":"IAD","dest":"LAX","rank":31},{"origin":"LAS","dest":"SJU","rank":21}]

使用下劃線,我能夠把這樣的東西扔在一起。但似乎效率低下,只返回重複的數組:

duplicates = _.chain(data).map(function (d) { 
    var ar = [d.origin, d.dest]; 
    return ar.sort(); 
}).sortBy(function (d) { 
    return d 
}).groupBy(function (d) {return d}).map(function (d) { 
    if (d.length > 1) { 
     return d[0] 
    } 
}).compact().value() 
single = _.chain(data).map(function (d) { 
    var ar = [d.origin, d.dest]; 
    return ar.sort(); 
}).sortBy(function (d) { 
    return d 
}).groupBy(function (d) { 
    return d 
}).map(function (d) { 
    if (d.length == 1) { 
     return d[0] 
    } 
}).compact().value() 

我不禁感到有一種更簡單的方法來得到這個。

回答

2

可能更容易引入一個臨時變量來保存組:

var data = [{"origin":"SJU","dest":"JFK","rank":48},{"origin":"JFK","dest":"SJU","rank":21},{"origin":"IAD","dest":"LAX","rank":31},{"origin":"LAS","dest":"SJU","rank":21}] 

var groups = _.groupBy(data, function(item) { 
    return [item.origin, item.dest].sort(); 
}); 

然後:

var duplicates = [], 
singles = []; 

_.each(groups, function(group) { 
    if (group.length > 1) { 
    duplicates.push.apply(duplicates, group); 
    } else { 
    singles.push(group[0]); 
    } 
}); 

Demo

+0

Ahhhh - 我不確定代碼末尾的[0]。但是,從這個角度來看,我能夠得到我需要的東西。簡單得多。謝謝!''singles = _.chain(groups).filter(function(group){return。group.length == 1; })。flatten()。value()'and'duplicates = _.chain(groups ).filter(function(group){return)返回group.length> 1; })。flatten()。值()' – user3760167

+0

@ user3760167是的,我一直在努力與Underscore那裏:)它應該現在返回正確的值。 –

+0

@ user3760167避免兩次過濾並且不需要它會更有效。只需一次建立'dupes'和'uniques'。 – plalx

0

我不明白你的代碼。但是我遇到了問題。

我看到它的方式是兩個步驟:

  • 識別重複並把它們壓在陣列中重複
  • 通過複製inital陣列創建uniquearray並刪除所有匹配重複數組的元素。

也許它具有較低的性能,但它可能會更清晰。

0

下面是使用普通的JavaScript的算法。如果你有成千上萬的記錄,它可能不是最有效的,但它完成了工作。

var data = [ 
    {"origin": "SJU", "dest": "JFK", "rank":48}, 
    {"origin": "JFK", "dest": "SJU", "rank":21}, 
    {"origin": "IAD", "dest": "LAX", "rank":31}, 
    {"origin": "LAS", "dest": "SJU", "rank":21} 
]; 

var uniques = []; 
var doubles = []; 

var i, j, l = data.length, origin, dest, foundDouble; 

for (i = 0; i < l; i += 1) { 
    origin = data[i].origin; 
    dest = data[i].dest; 
    foundDouble = false; 

    for (j = 0; j < l; j += 1) { 
     //skip the same row 
     if (i == j) { 
      continue; 
     } 

     if ((data[j].origin == origin || data[j].origin == dest) && (data[j].dest == origin || data[j].dest == dest)) { 
      doubles.push(data[i]); 
      foundDouble = true; 
     } 
    } 

    if (!foundDouble) { 
     uniques.push(data[i]); 
    } 
} 

console.log('Uniques', uniques); 
console.log('Doubles', doubles); 
0

有很多方法可以做到這一點,但這裏有一個。我從來沒有使用下劃線,但算法非常簡單,你應該能夠輕鬆地進行轉換。

var voyages = [{"origin":"SJU","dest":"JFK","rank":48},{"origin":"JFK","dest":"SJU","rank":21},{"origin":"IAD","dest":"LAX","rank":31},{"origin":"LAS","dest":"SJU","rank":21}], 
    dupes = [], 
    uniques = [], 
    countMap = new Map(), //Map is from Harmony, but you can use a plain object 
    voyageKeyOf = function (voyage) { return [voyage.origin, voyage.dest].sort().join(''); }, 
    uniques; 

//Create a map that stores how many times every voyage keys were seen 
voyages.forEach(function (voyage) { 
    var key = voyageKeyOf(voyage), 
     hasCount = countMap.get(key); 

    if (!hasCount) countMap.set(key, 1); 
    else { 
     let count = countMap.get(key); 
     countMap.set(key, ++count); 
    } 
}); 

voyages.forEach(function (voyage) { 
    var key = voyageKeyOf(voyage), 
     isUnique = countMap.get(key) == 1; 

    if (isUnique) uniques.push(voyage) 
    else dupes.push(voyage); 
}); 


console.log('uniques', uniques); 
console.log('dupes', dupes); 
+0

'Map'從哪裏來? –

+0

@Jack https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/Map它來自Harmony。我添加了一個註釋;) – plalx

+0

人們使用Underscore的原因是,他們不必擔心不同的瀏覽器版本...... –