我有以下資料:
const data = [
{
id: 1,
metadata: {
attributes: [
{
type: 'background',
value: 'red',
},
{
type: 'background',
value: 'blue',
},
{
type: 'size',
value: 'small',
},
],
},
},
{
id: 2,
metadata: {
attributes: [
{
type: 'background',
value: 'red',
},
{
type: 'background',
value: 'blue',
},
],
},
},
{
id: 3,
metadata: {
attributes: [
{
type: 'background',
value: 'red',
},
{
type: 'background',
value: 'green',
},
{
type: 'size',
value: 'small',
},
],
},
},
];
對于屬性陣列中的每個物件,我必須基于 type 屬性創建一個新物件。type 屬性將是這個新物件中的鍵,值將是嵌套在其中的另一個屬性。嵌套屬性的值將是一個包含所有相應 id 的陣列。所以,我必須實作這樣的最終結果:
const desiredResult = {
background: {
red: [1, 2, 3], //these are ids
blue: [1, 2],
green: [3],
},
size: {
small: [1, 3],
},
};
uj5u.com熱心網友回復:
您可以嘗試for each或for ... of在 javascript 中。初學者的干凈代碼如下:
function process (data) {
let result = {};
for (let datum of data) {
for (let attribute of datum.metadata.attributes) {
result[attribute.type] = result[attribute.type] || {};
result[attribute.type][attribute.value] = result[attribute.type][attribute.value] || [];
result[attribute.type][attribute.value].push(datum.id);
}
}
return result;
}
//
const desiredResult = process(data);
uj5u.com熱心網友回復:
您可以嘗試在 a內forEach的attributes屬性上使用 a reduce。
在 forEach 中,我正在檢查是否已經創建了子欄位(例如背景、大小)。如果不是,我將分配一個空物件。同樣對于型別內的值欄位也是如此。如果值欄位已經存在,我將在陣列中推送 id
const data = [ { id: 1, metadata: { attributes: [ { type: 'background', value: 'red', }, { type: 'background', value: 'blue', }, { type: 'size', value: 'small', }, ], }, }, { id: 2, metadata: { attributes: [ { type: 'background', value: 'red', }, { type: 'background', value: 'blue', }, ], }, }, { id: 3, metadata: { attributes: [ { type: 'background', value: 'red', }, { type: 'background', value: 'green', }, { type: 'size', value: 'small', }, ], }, },];
let res = data.reduce((acc,{id,metadata:{attributes}})=>{
attributes.forEach(({type,value}) => {
acc[type] = acc[type]||{}
acc[type][value] = acc[type][value] || []
acc[type][value].push(id)
})
return acc
},{})
console.log(res)
.as-console-wrapper { max-height: 100% !important; top: 0; }
uj5u.com熱心網友回復:
另一種方法與此處的其他方法非常相似,但使用不可變資料,即使對于累加器也是如此:
const extract = (xs) => xs .reduce ((a, {id, metadata: {attributes = []} = {}}) =>
attributes .reduce ((a, {type: t, value: v}) =>
({...a, [t]: {... (a [t] || {}), [v]: [...((a [t] || {}) [v] || []), id]}}),
a), {})
const data = [{id: 1, metadata: {attributes: [{type: "background", value: "red"}, {type: "background", value: "blue"}, {type: "size", value: "small"}]}}, {id: 2, metadata: {attributes: [{type: "background", value: "red"}, {type: "background", value: "blue"}]}}, {id: 3, metadata: {attributes: [{type: "background", value: "red"}, {type: "background", value: "green"}, {type: "size", value: "small"}]}}]
console .log (extract (data))
.as-console-wrapper {max-height: 100% !important; top: 0}
這適用于許多大小的資料,但如果資料非常大,它可能會遇到性能問題。如果你這樣做了,那么你可能不得不選擇一個可變的累加器。但是我不會擔心它,除非這個函式表明它本身是你應用程式的一個瓶頸。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/478420.html
標籤:javascript 算法
上一篇:python中A*實作的優化
