找到 JSON 对象 属性 匹配不止一次
Find a JSON object with property matched more than once
我需要找到 json 数组中具有相同名称的每个元素 属性 例如这里阿拉斯加是两次然后我需要比较两个对象的最后更新并选择一个有最新更新时间。采用 Whosebug 中的答案(抱歉,我丢失了 link)我可以删除具有相同名称的对象 属性 但是如何保留具有最新更新时间的对象?
[{
"name": "Alaska",
"Republican_fre": 3,
"Democrats_fre": 0,
"winner": "R",
"iso_2": "AK",
"electoral_vote": 3,
"totalComponents": 3,
"date": "29.06.2016",
"lastupdate": "1467233426"
}, {
"name": "Alabama",
"Republican_fre": 3,
"Democrats_fre": 0,
"winner": "R",
"iso_2": "AL",
"electoral_vote": 9,
"totalComponents": 3,
"date": "29.06.2016",
"lastupdate": "1467233426"
}, {
"name": "Arkansas",
"Republican_fre": 2,
"Democrats_fre": 0,
"winner": "R",
"iso_2": "AR",
"electoral_vote": 6,
"totalComponents": 2,
"date": "29.06.2016",
"lastupdate": "1467233426"
},
{
"name": "Alaska",
"Republican_fre": 5,
"Democrats_fre": 0,
"winner": "R",
"iso_2": "AK",
"electoral_vote": 3,
"totalComponents": 5,
"date": "29.06.2016",
"lastupdate": "1467282133"
}]
代码:
function arrUnique(arr) {
var cleaned = [];
data.forEach(function(itm) {
var unique = true;
cleaned.forEach(function(itm2) {
var minValue = Math.min(itm.lastupdate, itm2.lastupdate)
if (_.isEqual(itm.name, itm2.name)){
unique = false;
}
});
if (unique) cleaned.push(itm);
});
return cleaned;
}
var uniqueStandards = arrUnique(data);
预期输出
预期的输出是它保留具有最新 'lastupdate' 值的 Alsaka 对象之一。所以它首先检查具有相同名称的对象 属性 然后比较 lastupdate 值并保留具有最新值的对象
希望我理解正确。
您想获得按 max(lastupdate) 排序的不同值的输出数组。
此代码在我 described.It 调用数组分组时工作
var group = [];
arr.forEach(function(val, key)
{
if(!group[val.name])
group[val.name] = val;
else{
if(group[val.name].lastupdate < val.lastupdate)
group[val.name] = val;
}
}
);
console.log(group);
这是一种方法。使用名称作为键创建对象并根据 lastUpdate 更新对象,然后将对象映射到数组
function arrUnique(arr){
var tmp={};
arr.forEach(function(item) {
if(!tmp[item.name] || +item.lastupdate > +tmp[item.name].lastupdate){
tmp[item.name] = item ;
}
});
return Object.keys(tmp).map(function(key){
return tmp[key]
});
}
请注意,您的 lastUpdate 的字符串比较可能不会 return 正确的结果,这就是我转换为数字
的原因
我严重怀疑 JSON 是应用该操作的最佳格式。
如果你真的需要使用 JSON 最好在输入时检查它,并覆盖属性(或只是日期)。在那种情况下,您可以确保不存在重复项。
如果您在字符串中有任意值并且搜索重复项,这将是一项非常棘手的任务。显而易见的解决方案是订购它,然后在 O(nlogn) 时间内搜索重复项。如果我们使用散列,这个问题可以在 O(n) 复杂度中解决。
但是知道您有已知数量的状态,您应该为每个状态遍历数组。
foreach state in states
var choosenOne = {}
foreach item in array
if(choosenOne == {}) {
choosenOne = item;
} else {
if(item.name == state) {
if(choosenOne.lastupdate > item.lastupdate)
delete item;
} else {
delete choosenOne
choosenOne = item;
}
}
这只是应该在 O(50*n) ~ O(n) 中为您提供解决方案的算法
这是简单的 javascript 解决方案,使用 forEach
和 map
检查索引并通过 lastupdate 使用新对象更新。
var data = [{"name":"Alaska","Republican_fre":3,"Democrats_fre":0,"winner":"R","iso_2":"AK","electoral_vote":3,"totalComponents":3,"date":"29.06.2016","lastupdate":"1467233426"},{"name":"Alabama","Republican_fre":3,"Democrats_fre":0,"winner":"R","iso_2":"AL","electoral_vote":9,"totalComponents":3,"date":"29.06.2016","lastupdate":"1467233426"},{"name":"Arkansas","Republican_fre":2,"Democrats_fre":0,"winner":"R","iso_2":"AR","electoral_vote":6,"totalComponents":2,"date":"29.06.2016","lastupdate":"1467233426"},{"name":"Alaska","Republican_fre":5,"Democrats_fre":0,"winner":"R","iso_2":"AK","electoral_vote":3,"totalComponents":5,"date":"29.06.2016","lastupdate":"1467282133"}]
var result = [];
data.forEach(function(e) {
if(!this[e.name]) {
this[e.name] = e;
result.push(e);
} else {
var index = result.map(function(a) { return a.name}).indexOf(e.name);
if(e.lastupdate > result[index].lastupdate) result[index] = e;
}
}, {});
console.log(result)
您可以使用下划线 sortBy() to sort items in the collection by their lastupdate
key, reverse() to have all the items ordered by lastupdate
in descending order, and then use uniq() 来仅保留唯一的 name
项。
var uniqueStandards = _.uniq(_.sortBy(data, 'lastupdate').reverse(), 'name');
var data = [{
"name": "Alaska",
"Republican_fre": 3,
"Democrats_fre": 0,
"winner": "R",
"iso_2": "AK",
"electoral_vote": 3,
"totalComponents": 3,
"date": "29.06.2016",
"lastupdate": "1467233426"
}, {
"name": "Alabama",
"Republican_fre": 3,
"Democrats_fre": 0,
"winner": "R",
"iso_2": "AL",
"electoral_vote": 9,
"totalComponents": 3,
"date": "29.06.2016",
"lastupdate": "1467233426"
}, {
"name": "Arkansas",
"Republican_fre": 2,
"Democrats_fre": 0,
"winner": "R",
"iso_2": "AR",
"electoral_vote": 6,
"totalComponents": 2,
"date": "29.06.2016",
"lastupdate": "1467233426"
}, {
"name": "Alaska",
"Republican_fre": 5,
"Democrats_fre": 0,
"winner": "R",
"iso_2": "AK",
"electoral_vote": 3,
"totalComponents": 5,
"date": "29.06.2016",
"lastupdate": "1467282133"
}];
var uniqueStandards = _.uniq(_.sortBy(data, 'lastupdate').reverse(), 'name');
document.body.innerHTML = '<pre>' + JSON.stringify(uniqueStandards, 0, 4) + '</pre>';
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
普通 JS 解决方案是:
var uniqueStandards = data
.slice() // this makes sure that we're not mutating the original array
.sort(function(x, y) { return y.lastupdate - x.lastupdate; }) // sort in descending order
.filter(function(x) { // this ensure items with unique names
return (this[x.name]? false: (this[x.name] = true));
}, {});
var data = [{
"name": "Alaska",
"Republican_fre": 3,
"Democrats_fre": 0,
"winner": "R",
"iso_2": "AK",
"electoral_vote": 3,
"totalComponents": 3,
"date": "29.06.2016",
"lastupdate": "1467233426"
}, {
"name": "Alabama",
"Republican_fre": 3,
"Democrats_fre": 0,
"winner": "R",
"iso_2": "AL",
"electoral_vote": 9,
"totalComponents": 3,
"date": "29.06.2016",
"lastupdate": "1467233426"
}, {
"name": "Arkansas",
"Republican_fre": 2,
"Democrats_fre": 0,
"winner": "R",
"iso_2": "AR",
"electoral_vote": 6,
"totalComponents": 2,
"date": "29.06.2016",
"lastupdate": "1467233426"
}, {
"name": "Alaska",
"Republican_fre": 5,
"Democrats_fre": 0,
"winner": "R",
"iso_2": "AK",
"electoral_vote": 3,
"totalComponents": 5,
"date": "29.06.2016",
"lastupdate": "1467282133"
}];
var uniqueStandards = data
.slice() // this makes sure that we're not mutating the original array
.sort(function(x, y) { return y.lastupdate - x.lastupdate; }) // sort in descending order
.filter(function(x) { // this ensure items with unique names
return (this[x.name]? false: (this[x.name] = true));
}, {});
document.body.innerHTML = '<pre>' + JSON.stringify(uniqueStandards, 0, 4) + '</pre>';
或者,您可以 lodash 试试看:
var uniqueStandards = _(data).orderBy('lastupdate', 'desc').uniqBy('name').value();
上面的代码片段使用 orderBy() to order the collection by lastupdate
in descending order, and uniqBy() 来确保集合只有唯一的名称。
var data = [{
"name": "Alaska",
"Republican_fre": 3,
"Democrats_fre": 0,
"winner": "R",
"iso_2": "AK",
"electoral_vote": 3,
"totalComponents": 3,
"date": "29.06.2016",
"lastupdate": "1467233426"
}, {
"name": "Alabama",
"Republican_fre": 3,
"Democrats_fre": 0,
"winner": "R",
"iso_2": "AL",
"electoral_vote": 9,
"totalComponents": 3,
"date": "29.06.2016",
"lastupdate": "1467233426"
}, {
"name": "Arkansas",
"Republican_fre": 2,
"Democrats_fre": 0,
"winner": "R",
"iso_2": "AR",
"electoral_vote": 6,
"totalComponents": 2,
"date": "29.06.2016",
"lastupdate": "1467233426"
}, {
"name": "Alaska",
"Republican_fre": 5,
"Democrats_fre": 0,
"winner": "R",
"iso_2": "AK",
"electoral_vote": 3,
"totalComponents": 5,
"date": "29.06.2016",
"lastupdate": "1467282133"
}];
var uniqueStandards = _(data).orderBy('lastupdate', 'desc').uniqBy('name').value();
document.body.innerHTML = '<pre>' + JSON.stringify(uniqueStandards, 0, 4) + '</pre>';
<script src="https://cdn.jsdelivr.net/lodash/4.13.1/lodash.min.js"></script>
我需要找到 json 数组中具有相同名称的每个元素 属性 例如这里阿拉斯加是两次然后我需要比较两个对象的最后更新并选择一个有最新更新时间。采用 Whosebug 中的答案(抱歉,我丢失了 link)我可以删除具有相同名称的对象 属性 但是如何保留具有最新更新时间的对象?
[{
"name": "Alaska",
"Republican_fre": 3,
"Democrats_fre": 0,
"winner": "R",
"iso_2": "AK",
"electoral_vote": 3,
"totalComponents": 3,
"date": "29.06.2016",
"lastupdate": "1467233426"
}, {
"name": "Alabama",
"Republican_fre": 3,
"Democrats_fre": 0,
"winner": "R",
"iso_2": "AL",
"electoral_vote": 9,
"totalComponents": 3,
"date": "29.06.2016",
"lastupdate": "1467233426"
}, {
"name": "Arkansas",
"Republican_fre": 2,
"Democrats_fre": 0,
"winner": "R",
"iso_2": "AR",
"electoral_vote": 6,
"totalComponents": 2,
"date": "29.06.2016",
"lastupdate": "1467233426"
},
{
"name": "Alaska",
"Republican_fre": 5,
"Democrats_fre": 0,
"winner": "R",
"iso_2": "AK",
"electoral_vote": 3,
"totalComponents": 5,
"date": "29.06.2016",
"lastupdate": "1467282133"
}]
代码:
function arrUnique(arr) {
var cleaned = [];
data.forEach(function(itm) {
var unique = true;
cleaned.forEach(function(itm2) {
var minValue = Math.min(itm.lastupdate, itm2.lastupdate)
if (_.isEqual(itm.name, itm2.name)){
unique = false;
}
});
if (unique) cleaned.push(itm);
});
return cleaned;
}
var uniqueStandards = arrUnique(data);
预期输出 预期的输出是它保留具有最新 'lastupdate' 值的 Alsaka 对象之一。所以它首先检查具有相同名称的对象 属性 然后比较 lastupdate 值并保留具有最新值的对象
希望我理解正确。
您想获得按 max(lastupdate) 排序的不同值的输出数组。
此代码在我 described.It 调用数组分组时工作
var group = [];
arr.forEach(function(val, key)
{
if(!group[val.name])
group[val.name] = val;
else{
if(group[val.name].lastupdate < val.lastupdate)
group[val.name] = val;
}
}
);
console.log(group);
这是一种方法。使用名称作为键创建对象并根据 lastUpdate 更新对象,然后将对象映射到数组
function arrUnique(arr){
var tmp={};
arr.forEach(function(item) {
if(!tmp[item.name] || +item.lastupdate > +tmp[item.name].lastupdate){
tmp[item.name] = item ;
}
});
return Object.keys(tmp).map(function(key){
return tmp[key]
});
}
请注意,您的 lastUpdate 的字符串比较可能不会 return 正确的结果,这就是我转换为数字
的原因我严重怀疑 JSON 是应用该操作的最佳格式。
如果你真的需要使用 JSON 最好在输入时检查它,并覆盖属性(或只是日期)。在那种情况下,您可以确保不存在重复项。
如果您在字符串中有任意值并且搜索重复项,这将是一项非常棘手的任务。显而易见的解决方案是订购它,然后在 O(nlogn) 时间内搜索重复项。如果我们使用散列,这个问题可以在 O(n) 复杂度中解决。
但是知道您有已知数量的状态,您应该为每个状态遍历数组。
foreach state in states
var choosenOne = {}
foreach item in array
if(choosenOne == {}) {
choosenOne = item;
} else {
if(item.name == state) {
if(choosenOne.lastupdate > item.lastupdate)
delete item;
} else {
delete choosenOne
choosenOne = item;
}
}
这只是应该在 O(50*n) ~ O(n) 中为您提供解决方案的算法
这是简单的 javascript 解决方案,使用 forEach
和 map
检查索引并通过 lastupdate 使用新对象更新。
var data = [{"name":"Alaska","Republican_fre":3,"Democrats_fre":0,"winner":"R","iso_2":"AK","electoral_vote":3,"totalComponents":3,"date":"29.06.2016","lastupdate":"1467233426"},{"name":"Alabama","Republican_fre":3,"Democrats_fre":0,"winner":"R","iso_2":"AL","electoral_vote":9,"totalComponents":3,"date":"29.06.2016","lastupdate":"1467233426"},{"name":"Arkansas","Republican_fre":2,"Democrats_fre":0,"winner":"R","iso_2":"AR","electoral_vote":6,"totalComponents":2,"date":"29.06.2016","lastupdate":"1467233426"},{"name":"Alaska","Republican_fre":5,"Democrats_fre":0,"winner":"R","iso_2":"AK","electoral_vote":3,"totalComponents":5,"date":"29.06.2016","lastupdate":"1467282133"}]
var result = [];
data.forEach(function(e) {
if(!this[e.name]) {
this[e.name] = e;
result.push(e);
} else {
var index = result.map(function(a) { return a.name}).indexOf(e.name);
if(e.lastupdate > result[index].lastupdate) result[index] = e;
}
}, {});
console.log(result)
您可以使用下划线 sortBy() to sort items in the collection by their lastupdate
key, reverse() to have all the items ordered by lastupdate
in descending order, and then use uniq() 来仅保留唯一的 name
项。
var uniqueStandards = _.uniq(_.sortBy(data, 'lastupdate').reverse(), 'name');
var data = [{
"name": "Alaska",
"Republican_fre": 3,
"Democrats_fre": 0,
"winner": "R",
"iso_2": "AK",
"electoral_vote": 3,
"totalComponents": 3,
"date": "29.06.2016",
"lastupdate": "1467233426"
}, {
"name": "Alabama",
"Republican_fre": 3,
"Democrats_fre": 0,
"winner": "R",
"iso_2": "AL",
"electoral_vote": 9,
"totalComponents": 3,
"date": "29.06.2016",
"lastupdate": "1467233426"
}, {
"name": "Arkansas",
"Republican_fre": 2,
"Democrats_fre": 0,
"winner": "R",
"iso_2": "AR",
"electoral_vote": 6,
"totalComponents": 2,
"date": "29.06.2016",
"lastupdate": "1467233426"
}, {
"name": "Alaska",
"Republican_fre": 5,
"Democrats_fre": 0,
"winner": "R",
"iso_2": "AK",
"electoral_vote": 3,
"totalComponents": 5,
"date": "29.06.2016",
"lastupdate": "1467282133"
}];
var uniqueStandards = _.uniq(_.sortBy(data, 'lastupdate').reverse(), 'name');
document.body.innerHTML = '<pre>' + JSON.stringify(uniqueStandards, 0, 4) + '</pre>';
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
普通 JS 解决方案是:
var uniqueStandards = data
.slice() // this makes sure that we're not mutating the original array
.sort(function(x, y) { return y.lastupdate - x.lastupdate; }) // sort in descending order
.filter(function(x) { // this ensure items with unique names
return (this[x.name]? false: (this[x.name] = true));
}, {});
var data = [{
"name": "Alaska",
"Republican_fre": 3,
"Democrats_fre": 0,
"winner": "R",
"iso_2": "AK",
"electoral_vote": 3,
"totalComponents": 3,
"date": "29.06.2016",
"lastupdate": "1467233426"
}, {
"name": "Alabama",
"Republican_fre": 3,
"Democrats_fre": 0,
"winner": "R",
"iso_2": "AL",
"electoral_vote": 9,
"totalComponents": 3,
"date": "29.06.2016",
"lastupdate": "1467233426"
}, {
"name": "Arkansas",
"Republican_fre": 2,
"Democrats_fre": 0,
"winner": "R",
"iso_2": "AR",
"electoral_vote": 6,
"totalComponents": 2,
"date": "29.06.2016",
"lastupdate": "1467233426"
}, {
"name": "Alaska",
"Republican_fre": 5,
"Democrats_fre": 0,
"winner": "R",
"iso_2": "AK",
"electoral_vote": 3,
"totalComponents": 5,
"date": "29.06.2016",
"lastupdate": "1467282133"
}];
var uniqueStandards = data
.slice() // this makes sure that we're not mutating the original array
.sort(function(x, y) { return y.lastupdate - x.lastupdate; }) // sort in descending order
.filter(function(x) { // this ensure items with unique names
return (this[x.name]? false: (this[x.name] = true));
}, {});
document.body.innerHTML = '<pre>' + JSON.stringify(uniqueStandards, 0, 4) + '</pre>';
或者,您可以 lodash 试试看:
var uniqueStandards = _(data).orderBy('lastupdate', 'desc').uniqBy('name').value();
上面的代码片段使用 orderBy() to order the collection by lastupdate
in descending order, and uniqBy() 来确保集合只有唯一的名称。
var data = [{
"name": "Alaska",
"Republican_fre": 3,
"Democrats_fre": 0,
"winner": "R",
"iso_2": "AK",
"electoral_vote": 3,
"totalComponents": 3,
"date": "29.06.2016",
"lastupdate": "1467233426"
}, {
"name": "Alabama",
"Republican_fre": 3,
"Democrats_fre": 0,
"winner": "R",
"iso_2": "AL",
"electoral_vote": 9,
"totalComponents": 3,
"date": "29.06.2016",
"lastupdate": "1467233426"
}, {
"name": "Arkansas",
"Republican_fre": 2,
"Democrats_fre": 0,
"winner": "R",
"iso_2": "AR",
"electoral_vote": 6,
"totalComponents": 2,
"date": "29.06.2016",
"lastupdate": "1467233426"
}, {
"name": "Alaska",
"Republican_fre": 5,
"Democrats_fre": 0,
"winner": "R",
"iso_2": "AK",
"electoral_vote": 3,
"totalComponents": 5,
"date": "29.06.2016",
"lastupdate": "1467282133"
}];
var uniqueStandards = _(data).orderBy('lastupdate', 'desc').uniqBy('name').value();
document.body.innerHTML = '<pre>' + JSON.stringify(uniqueStandards, 0, 4) + '</pre>';
<script src="https://cdn.jsdelivr.net/lodash/4.13.1/lodash.min.js"></script>