假設一個具有不一致屬性的陣列,如下所示:
[
{user: 'user1', comment: 'This is a comment',},
{user: 'user1', role: 'member'},
{user: 'user1', role: 'writer'},
{user: 'user2', role: 'admin'},
{user: 'user1', comment: 'This is another comment'},
]
如何將其轉換為僅當陣列中的下一個元素具有相同屬性且屬于同一用戶時才會對物件進行分組:
[
{user: 'user1', comment: 'This is a comment'},
{user: 'user1', role: [{'member', 'writer'}]},
{user: 'user2', role: 'admin'},
{user: 'user1', comment: 'This is another comment'},
]
uj5u.com熱心網友回復:
該解決方案也作為reduce任務實施。
迭代任務采用lookbehind 方法,將當前用戶專案與前一個用戶專案進行比較。如果滿足兩個匹配條件(相同的用戶名和相同的屬性名),則該程序會嘗試查找merger將通過該collector物件參考的已經存在的物件。如果以前的合并沒有發生,merger則從以前的用戶項創建一個新物件并分配給collector. 在任何情況下,合并都將由當前處理的用戶項聚合。
function mergeConsecutiveSameSoleUserEntry(collector, userItem, idx, arr) {
let { merger, result } = collector;
if (idx >= 1) {
const { user: userName, ...soleEntry } = userItem;
const { user: prevUserName, ...prevSoleEntry } = arr[idx - 1] ?? {};
if (userName === prevUserName) {
const [soleKey, soleValue] = Object.entries(soleEntry).at(0);
const [prevSoleKey, prevSoleValue] = Object.entries(prevSoleEntry).at(0);
if (soleKey === prevSoleKey) {
if (!merger) {
merger = collector.merger = {
user: userName,
[soleKey]: [prevSoleValue],
};
result[result.length - 1] = merger;
}
merger[soleKey].push(soleValue);
} else {
Reflect.deleteProperty(collector, 'merger');
result.push(userItem);
}
} else {
Reflect.deleteProperty(collector, 'merger');
result.push(userItem);
}
} else {
Reflect.deleteProperty(collector, 'merger');
result.push(userItem);
}
return collector;
}
console.log([
{ user: 'user1', comment: 'This is a comment' },
{ user: 'user1', role: 'member' },
{ user: 'user1', role: 'writer' },
{ user: 'user1', role: 'observer' },
{ user: 'user2', comment: 'This is a comment' },
{ user: 'user2', role: 'writer' },
{ user: 'user2', role: 'admin' },
{ user: 'user1', role: 'admin' },
{ user: 'user1', role: 'observer' },
{ user: 'user1', comment: 'This is another comment' },
].reduce(mergeConsecutiveSameSoleUserEntry, { result: [] }).result);
.as-console-wrapper { min-height: 100%!important; top: 0; }
uj5u.com熱心網友回復:
你可以試試這樣的遞回函式
let data = [
{ user: 'user1', comment: 'This is a comment' },
{ user: 'user1', role: 'member' },
{ user: 'user1', role: 'writer' },
{ user: 'user2', role: 'admin' },
{ user: 'user1', comment: 'This is another comment' },
];
let combined = []
const combineRole = (curr, next, data) => {
if (curr.user == next?.user && curr.role && next.role) {
curr.role = [curr.role, next.role].flat().filter(Boolean)
return combineRole(curr, data.shift(), data)
} else {
return [curr, next]
}
}
while (data.length) {
// console.log(data)
let [curr, next] = (combineRole(data.shift(), data.shift(), data))
if (next)
data.unshift(next)
combined.push(curr)
}
console.log(combined)
.as-console-wrapper { min-height: 100%!important; top: 0; }
uj5u.com熱心網友回復:
您可以使用 reduce 來制作類似的東西
const datas = [
{ user: 'user1', comment: 'This is a comment' },
{ user: 'user1', role: 'member' },
{ user: 'user1', role: 'writer' },
{ user: 'user1', role: 'observer' },
{ user: 'user2', comment: 'This is a comment' },
{ user: 'user2', role: 'writer' },
{ user: 'user2', role: 'admin' },
{ user: 'user1', role: 'admin' },
{ user: 'user1', role: 'observer' },
{ user: 'user1', comment: 'This is another comment' },
]
const datas2 = datas.reduce((s, d, x) => {
if (x > 0) {
const dk = Object.keys(d)
if (dk.join(',') === Object.keys(s[s.length - 1]).join(',') && d.user === s[s.length - 1].user) {
for (const k in dk) {
if (dk[k] !== 'user' && d.hasOwnProperty(dk[k]) && s[s.length - 1].hasOwnProperty(dk[k])) {
if (typeof s[s.length - 1][dk[k]] !== 'object')
s[s.length - 1][dk[k]] = [s[s.length - 1][dk[k]]]
s[s.length - 1][dk[k]].push(d[dk[k]])
}
}
return s
}
}
return s.concat(d)
}, [])
console.log(datas2);
.as-console-wrapper { min-height: 100%!important; top: 0; }
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/417443.html
標籤:
上一篇:如何解構我的多個物件陣列
