我是javascript的新手,我的JSON数组包含一些重复的键,如下所示:
var connections = [
{
"source":"l1",
"target":"l2",
"metrics": { "normal":20 },
"metadata": { "streaming": 1 }
},
{
"source":"l2",
"target":"l3",
"metrics": { "normal":30 },
"metadata": { "streaming": 1 }
},
{
"source":"l2",
"target":"l3",
"metrics": { "normal":25 },
"metadata": { "streaming": 1 }
},
{
"source":"l3",
"target":"l4",
"metrics": { "normal":24 },
"metadata": { "streaming": 1 }
},
{
"source":"l3",
"target":"l4",
"metrics": { "normal":21 },
"metadata": { "streaming": 1 }
},
{
"source":"l3",
"target":"l4",
"metrics": { "normal":20 },
"metadata": { "streaming": 1 }
},
]
现在我想要合并具有相同“source”和“target”值的重复JSON,并且键“normal”应该是所有相同源和目标的最大值。 所以给出的例子的答案是:
var answer =[
{
"source":"l1",
"target":"l2",
"metrics": { "normal":20 },
"metadata": { "streaming": 1 }
},
{
"source":"l2",
"target":"l3",
"metrics": { "normal":30 },
"metadata": { "streaming": 1 }
},
{
"source":"l3",
"target":"l4",
"metrics": { "normal":24 },
"metadata": { "streaming": 1 }
},
]
这只是一个用不同对象进行的示例对象。我不知道如何解决这个问题, 我认为下划线或lodash可以很容易地解决这个问题,但任何解决方案都可以接受。
答案 0 :(得分:1)
使用_.groupBy()
按来源和目标收集对象。使用_.map()
和Array#reduce来获取每个组中具有最大normal
值的那个。
var connections = [{"source":"l1","target":"l2","metrics":{"normal":20},"metadata":{"streaming":1}},{"source":"l2","target":"l3","metrics":{"normal":30},"metadata":{"streaming":1}},{"source":"l2","target":"l3","metrics":{"normal":25},"metadata":{"streaming":1}},{"source":"l3","target":"l4","metrics":{"normal":24},"metadata":{"streaming":1}},{"source":"l3","target":"l4","metrics":{"normal":21},"metadata":{"streaming":1}},{"source":"l3","target":"l4","metrics":{"normal":20},"metadata":{"streaming":1}}];
var result = _(connections)
.groupBy(function(o) { // group by source and target
return o.source + '-' + o.target;
})
.map(function(arr) { // map the groups to values
return arr.reduce(function(max, o) { // get the object with the hight normal in each group
return max.metrics.normal > o.metrics.normal ? max : o;
});
})
.value();
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
答案 1 :(得分:1)
您可以将对象用作地图,将source
+ target
作为关键字,将connections
的对象作为值,保留每个source
组合的指标最高的对象{1}} + target
:
var connections = [
{"source": "l1", "target": "l2", "metrics": {"normal": 20}, "metadata": {"streaming": 1} },
{"source": "l2", "target": "l3", "metrics": {"normal": 30}, "metadata": {"streaming": 1} },
{"source": "l2", "target": "l3", "metrics": {"normal": 25}, "metadata": {"streaming": 1} },
{"source": "l3", "target": "l4", "metrics": {"normal": 24}, "metadata": {"streaming": 1} },
{"source": "l3", "target": "l4", "metrics": {"normal": 21}, "metadata": {"streaming": 1} },
{"source": "l3", "target": "l4", "metrics": {"normal": 20}, "metadata": {"streaming": 1} }
];
var map = {};
connections.forEach((connection) => {
var mapKey = connection.source + "/" + connection.target;
answerConnection = map[mapKey];
if (!answerConnection || answerConnection.metrics.normal < connection.metrics.normal)
map[mapKey] = connection;
});
var answer = Object.values(map);
console.log(answer);
答案 2 :(得分:0)
您可以根据目标和源相同将阵列缩减为新阵列,然后检查指标是否超过以前存储的值
var connections = [
{"source": "l1", "target": "l2", "metrics": {"normal": 20}, "metadata": {"streaming": 1} },
{"source": "l2", "target": "l3", "metrics": {"normal": 30}, "metadata": {"streaming": 1} },
{"source": "l2", "target": "l3", "metrics": {"normal": 25}, "metadata": {"streaming": 1} },
{"source": "l3", "target": "l4", "metrics": {"normal": 24}, "metadata": {"streaming": 1} },
{"source": "l3", "target": "l4", "metrics": {"normal": 21}, "metadata": {"streaming": 1} },
{"source": "l3", "target": "l4", "metrics": {"normal": 20}, "metadata": {"streaming": 1} }
]
var res = connections.reduce( (a,b) => {
let i = a.findIndex( item => item.target === b.target && item.source === b.source);
if (i===-1) {
a.push(b);
} else if (a[i].metrics.normal < b.metrics.normal) {
a[i] = b;
}
return a;
}, []);
document.body.innerHTML = '<pre>' + JSON.stringify(res,0,4) + '</pre>'