[英]Remove object in Array of Objects if few key-value pair are same and another key-value are less than other object
我有這種類型的對象
var array = [
{ "foo": 1, "bar": 2, "baz": 3 },
{ "foo": 1, "bar": 2, "baz": 5 },
{ "foo": 1, "bar": 2, "baz": 4 },
{ "foo": 2, "bar": 1, "baz": 3 },
{ "foo": 2, "bar": 1, "baz": 7 },
{ "foo": 1, "bar": 3, "baz": 4 }
]
如果'foo'和'bar'鍵值相同,則選擇鍵'baz'更大的值並刪除其他對象。
像這樣
[ { "foo": 1, "bar": 2, "baz": 5 },
{ "foo": 2, "bar": 1, "baz": 7 },
{ "foo": 1, "bar": 3, "baz": 4 } ]
那么,下划線/ lodash庫或僅在javascript中的解決方案是什么?
使用lodash可以將foo
和baz
的值組合在一起。 然后映射結果,並在每個組中選擇具有最高baz
值的對象:
var array = [ { "foo": 1, "bar": 2, "baz": 3 }, { "foo": 1, "bar": 2, "baz": 5 }, { "foo": 1, "bar": 2, "baz": 4 }, { "foo": 2, "bar": 1, "baz": 3 }, { "foo": 2, "bar": 1, "baz": 7 }, { "foo": 1, "bar": 3, "baz": 4 } ] var result = _.map( _.groupBy(array, o => `${o.foo}-${o.bar}`), g => _.maxBy(g, 'baz') ) console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
使用Vanilla JS,您可以對累加器鍵使用類似的約定( bar
和baz
組合),將數組簡化為一個對象(累加器)。 只要數組中的對象和存儲在累加器中的對象具有相同的鍵,就會保留具有最高baz
值的鍵。
const array = [ { "foo": 1, "bar": 2, "baz": 3 }, { "foo": 1, "bar": 2, "baz": 5 }, { "foo": 1, "bar": 2, "baz": 4 }, { "foo": 2, "bar": 1, "baz": 3 }, { "foo": 2, "bar": 1, "baz": 7 }, { "foo": 1, "bar": 3, "baz": 4 } ] const result = Object.values(array.reduce((r, o) => { const key = `${o.foo}-${o.bar}` if(!r[key] || r[key].baz < o.baz) r[key] = o return r }, {})) console.log(result)
另一種可能性是按照foo
和bar
的升序和baz
降序對數組進行排序,然后進行reduce
。
var array = [ { "foo": 1, "bar": 2, "baz": 3 }, { "foo": 1, "bar": 2, "baz": 5 }, { "foo": 1, "bar": 2, "baz": 4 }, { "foo": 2, "bar": 1, "baz": 3 }, { "foo": 2, "bar": 1, "baz": 7 }, { "foo": 1, "bar": 3, "baz": 4 } ]; const res = array .sort((a, b) => a.foo - b.foo || a.bar - b.bar || b.baz - a.baz) .reduce((acc, curr) => { const prev = acc[acc.length - 1] || {}; if (!(curr.foo === prev.foo && curr.bar === prev.bar)) acc.push(curr); return acc; }, []); console.log(res);
我嘗試了這種解決方案 ,對我來說很有效,
這是解決方案
var result = ab.reduce((p,c) => {var o = p.find(e => e.foo === c.foo && e.bar === c.bar);
!!o ? o.baz = (o.baz > c.baz ? o.baz : c.baz) : p.push(c);
return p;},[]);
但是我不明白這段代碼的流程。 因此,我決定擴展代碼並嘗試理解代碼
var result = ab.reduce((newArray, singleObj) => {
var sameKeyValueObj = newArray.find(obj => {
return obj.foo === singleObj.foo && obj.bar === singleObj.bar
});
sameKeyValueObj ? sameKeyValueObj.baz = (
sameKeyValueObj.baz > singleObj.baz ? sameKeyValueObj.baz : singleObj.baz
) : newArray.push(singleObj);
return newArray;
}, []);
這對我來說是一個可以理解的解決方案。 如果有人有另一個好的解決方案,請告訴我。
您還可以先執行orderBy ...然后執行keyBy ,最后執行值以獲取所需的內容:
var array = [ { "foo": 1, "bar": 2, "baz": 3 }, { "foo": 1, "bar": 2, "baz": 5 }, { "foo": 1, "bar": 2, "baz": 4 }, { "foo": 2, "bar": 1, "baz": 3 }, { "foo": 2, "bar": 1, "baz": 7 }, { "foo": 1, "bar": 3, "baz": 4 } ] const result = _.values(_.keyBy( _.orderBy(array, ['foo', 'bar', 'baz']), x=>`${x.foo}-${x.bar}`)) console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
或者你可以連鎖它,以及通過:
const result = _(array)
.orderBy(['foo', 'bar', 'baz'])
.keyBy(x => `${x.foo}-${x.bar}`)
.values()
.value()
const array = [ { foo: 1, bar: 2, baz: 3 }, { foo: 1, bar: 2, baz: 5 }, { foo: 1, bar: 2, baz: 4 }, { foo: 2, bar: 1, baz: 3 }, { foo: 2, bar: 1, baz: 7 }, { foo: 1, bar: 3, baz: 4 } ]; const result = array.reduce((result, obj) => { const resultObj = result.find(resultObj => obj.foo === resultObj.foo && obj.bar === resultObj.bar); if (!resultObj) { return [ ...result, obj ]; } if (resultObj.baz > obj.baz) { return result; } return [ ...result.filter(obj => obj !== resultObj), obj ]; }, []); console.log(result);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.