Javascript 过滤器独特&;使用下划线在数组中复制对象
我有一个对象数组:Javascript 过滤器独特&;使用下划线在数组中复制对象,javascript,underscore.js,Javascript,Underscore.js,我有一个对象数组: 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}] 我正试图通过“origin”和“dest”提取所有重复和唯一的对象。因此这两个是相同的,忽略秩键 {来源:JFK,目的地:SJU,排名:2
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}]
我正试图通过“origin”和“dest”提取所有重复和唯一的对象。因此这两个是相同的,忽略秩键
{来源:JFK,目的地:SJU,排名:21}
{“来源”:“SJU”,“目的地”:“JFK”,“等级”:48}
duplicates=[{“原点”:“SJU”,“目标”:“JFK”,“等级”:48},{“原点”:“JFK”,“目标”:“SJU”,“等级”: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()
我忍不住觉得有一种更简单的方法来实现这一点。我不理解您的代码。但是我遇到了问题 在我看来,这是两个步骤:
- 识别重复项并将其推送到重复项数组中
- 通过复制初始数组创建uniquearray,并删除与重复数组匹配的所有元素
也许它的性能较低,但可能更清晰。引入一个临时变量来保存组可能更容易:
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();
});
然后:
以下是使用纯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 );
var数据=[
{“来源”:“SJU”,“目的地”:“JFK”,“等级”:48},
{“来源”:“JFK”,“目的地”:“SJU”,“等级”:21},
{“来源”:“IAD”,“目的地”:“LAX”,“等级”:31},
{“来源”:“LAS”,“目的地”:“SJU”,“等级”:21}
];
var uniques=[];
var Double=[];
变量i,j,l=数据长度,原点,终点,foundDouble;
对于(i=0;i
有很多方法可以做到这一点,但这里有一种。我从未使用下划线,但算法非常简单,您应该能够轻松地转换它
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]。但从这一点上,我能够得到我所需要的。简单得多。谢谢
singles=..chain(groups).filter(function(group){return group.length==1;}).flatte().value()
和duplicates=..chain(groups).filter(function(group){return group.length>1;}).flatte().value()
@user3760167是的,我在那里挣扎了一段时间:)它现在应该返回正确的值了。@user3760167避免两次过滤会更有效,而且不需要它。只需在一次运行中构建dups
和uniques
。谢谢!我没想过不用锁链就能做到。。。我认为缺少的最后一件事是返回单个重复数组:duplicates=u.flatte(u.filter(组,函数(组){return group.length>1;}).map(函数(项){return item;})代码>@Jack太酷了,什么时候我们可以通知多个这样的用户/cc:@user3760167?无论如何,这样的算法更好;)Map
从哪里来?@Jack它来自Harmony。我加了一张便条;)人们使用下划线的原因是,他们不必担心不同的浏览器版本…@Jack Yes和下划线是一个很好的抽象概念。我不是建议使用此代码,我说它可以很容易地移植到下划线,但我从未使用过它,因此与已经知道它的人相比,移植它需要更多的时间。我也从未使用下划线;-)
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);