簡體   English   中英

如果幾個鍵值對相同​​且另一個鍵值小於其他對象,則從對象數組中刪除對象

[英]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可以將foobaz的值組合在一起。 然后映射結果,並在每個組中選擇具有最高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,您可以對累加器鍵使用類似的約定( barbaz組合),將數組簡化為一個對象(累加器)。 只要數組中的對象和存儲在累加器中的對象具有相同的鍵,就會保留具有最高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) 

另一種可能性是按照foobar的升序和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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM