簡體   English   中英

按嵌套屬性對對象進行分組的更優雅的方式

[英]More elegant way to group objects by nested attribute

我從第三方 API 獲取數據,無法事先過濾。 我有以下數組:

[
 [
  User1 {
    attr1: 'abc',
    attr2: ['0x1', '0xa']
  },
  User2 {
    attr1: 'def'
    attr2: ['0x1', '0xb']
  }
 ]
 [
  User3 {
    attr1: 'ghi',
    attr2: ['0x1', '0xa']
  },
  User4 {
    attr1: 'jkl',
    attr2: ['0x1', '0xb']
  },
  User5 {
    attr1: 'mno',
    attr2: ['0x1', '0xc']
  } 
 ]
]

目標是獲得以下內容。 本質上,我想根據 attr2[1] 對用戶進行分組,並過濾掉沒有配對的用戶。 關鍵是 attr2[1]。

[
 {
   attr2_1: '0xa',
   attrs: [User1, User3]
 },
 {
   attr2_1: '0xb',
   attrs: [User2, User4]
 }
]

我有一個可行的解決方案,但我想知道如何更優雅地解決它。

我按第二個屬性對用戶進行分組

const usersByParam = _.chain(allUsers)
       .flatten()
       .groupBy(user => user.attr2[1])
       .value()
   

我過濾分組的用戶以刪除沒有配對的條目(示例中的 User5)

const filteredUsers = _.omitBy(usersByParam, (val) => {return val.length < 2})

我通過過濾結果go得到我的用戶對象

for (const key in filteredUsers) {
  userArray.push({attr2_1: key, attrs: filteredUsers[key]} as User)
}

它給了我想要的東西,但我相信有更優雅的方法來解決它。

您可以使用 JavaScript:

 const data = [{User1: {attr1: 'abc',attr2: ['0x1', '0xa']}},{User2: {attr1: 'def',attr2: ['0x1', '0xb']}},{User3: {attr1: 'ghi',attr2: ['0x1', '0xa']}},{User4: {attr1: 'jkl',attr2: ['0x1', '0xb']}},{User5: {attr1: 'mno',attr2: ['0x1', '0xc']}}] const result = Object.entries( data.reduce((a, c) => { const [k] = Object.keys(c) a[c[k].attr2[1]] = [...(a[c[k].attr2[1]] || []), k] return a }, {}) ).filter(([, users]) => users.length > 1).map(([attr2_1, attrs]) => ({ attr2_1, attrs })) console.log(result)

您發布的數據無效 JSON。因此,假設它應該是一個對象數組,我在下面的代碼中對其進行了修改以反映這一點。

我不確定如何在 lodash 中執行此操作,但您可以使用 vanilla JavaScript 來完成此操作。 通過使用Array.reduce()Array.filter()方法,您可以根據需要操作數據。

請參閱下面的片段。

 const data = [{ User1: { attr1: 'abc', attr2: ['0x1', '0xa'] } }, { User2: { attr1: 'def', attr2: ['0x1', '0xb'] } }, { User3: { attr1: 'ghi', attr2: ['0x1', '0xa'] } }, { User4: { attr1: 'jkl', attr2: ['0x1', '0xb'] } }, { User5: { attr1: 'mno', attr2: ['0x1', '0xc'] } } ]; const reduced = Object.values(data.reduce((a, c) => { var user = Object.keys(c)[0]; var key = c[user].attr2[1]; a[key]??= {}; a[key].attr2_1 = key; a[key].attrs??= []; a[key].attrs.push(user); return a; }, {})).filter(element => element.attrs.length === 2); console.log(reduced);

您的代碼已經很優雅了,我只是將for... in替換為map

const userArray = _.chain(allUsers)
  .flatten()
  .groupBy(user => user.attr2[1])
  .omitBy(val => val.length < 2)
  .map((attrs, attr2_1) => ({ attr2_1, attrs }))
  .value();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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