我有一个对象数组:
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“origin”& “目标”。所以这两个是相同的,忽略了等级键
{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()
我不禁觉得有一种更简单的方法可以解决这个问题。
答案 0 :(得分: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]);
}
});
答案 1 :(得分:0)
我不理解你的代码。但是我遇到了问题。
我看到的方式是两步:
可能性能较低但可能更清晰。
答案 2 :(得分: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 );
答案 3 :(得分: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);