[英]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.