2017-05-31 150 views
0

我想過濾與models數組中的「model」鍵匹配的items數組對象,並將它們存儲在數組中。我的努力取得了成功,但我對我的努力並不滿意。有沒有更好的方法來做到這一點?使用多個數組過濾嵌套的JSON對象並將過濾的對象存儲在數組中

有關如何使用underscore.js和lodash執行操作的任何建議?或者使用本地JavaScript映射和過濾器功能?

JSON對象

{ 
"items": [ 
    { 
    "model": "ooc0d", 
    "code": "2x4qr", 
    "price": 33 
    }, 
    { 
    "model": "ruie9", 
    "code": "2f6gi", 
    "price": 22 
    }, 
    { 
    "model": "aqu0d", 
    "code": "2f6gi", 
    "price": 21 
    }, 
    { 
    "model": "ddebd", 
    "code": "2f6gi", 
    "price": 25 
    }, 
    { 
    "model": "ddebd", 
    "code": "2f6gi", 
    "price": 29 
    } 
], 
"models": [ 
    { 
    "model": "ruie9", 
    "year": 1998 
    }, 
    { 
    "model": "ooc0d", 
    "year": 1991 
    }, 
    { 
    "model": "aqu0d", 
    "year": 1994 
    }, 
    { 
    "model": "ddebd", 
    "year": 1995 
    }, 
    { 
    "model": "odq76", 
    "year": 1999 
    } 
] 
} 

我的解決方案

const { models, items } = jsonData; 

const newarray = []; 

for(let i = 0; i < models.length; i++) { 
    for(let j = 0; j < items.length; j++) { 
    if(items[j].model===models[i].model) { 

     let obj = { 
     ...items[j], 
     year: models[i].year 
     } 
     newarray.push(obj); 
    } 
    } 
} 
+1

您訪問'id'財產,但有你的JSON – quirimmo

+0

不跟蹤id屬性哎呀對不起。剛剛糾正 – 1033

+0

@創建了這個[基準](https://jsfiddle.net/sf5jtru6/)與我Umair和Pankaj。 Pankaj獲勝:) –

回答

1

可以重寫

let obj = { 
    ...items[j], 
    year: models[i].year 
} 

let obj = Object.assign({}, items[j], { year: models[i].year }); 

而且你還可以使用Array.prototype.forEach代替for循環,像這樣

models.forEach((m) => { 
    items.forEach((i) => { 
    if (m.id === i.id) { 
     let obj = Object.assign({}, i, { year: m.year }); 

     newArray.push(obj); 
    } 
    }) 
}) 

我試圖保持它類似於您的解決方案成爲可能。

+0

謝謝你!它看起來更乾淨:D – 1033

1

試試這個片斷:

const jsonData = { 
 
    "items": [{ 
 
     "model": "ooc0d", 
 
     "code": "2x4qr", 
 
     "price": 33 
 
    }, 
 
    { 
 
     "model": "ruie9", 
 
     "code": "2f6gi", 
 
     "price": 22 
 
    }, 
 
    { 
 
     "model": "aqu0d", 
 
     "code": "2f6gi", 
 
     "price": 21 
 
    }, 
 
    { 
 
     "model": "ddebd", 
 
     "code": "2f6gi", 
 
     "price": 25 
 
    }, 
 
    { 
 
     "model": "ddebd", 
 
     "code": "2f6gi", 
 
     "price": 29 
 
    } 
 
    ], 
 
    "models": [{ 
 
     "model": "ruie9", 
 
     "year": 1998 
 
    }, 
 
    { 
 
     "model": "ooc0d", 
 
     "year": 1991 
 
    }, 
 
    { 
 
     "model": "aqu0d", 
 
     "year": 1994 
 
    }, 
 
    { 
 
     "model": "ddebd", 
 
     "year": 1995 
 
    }, 
 
    { 
 
     "model": "odq76", 
 
     "year": 1999 
 
    } 
 
    ] 
 
}; 
 

 
var newArray = jsonData.models.reduce(
 
    (acc, modelData) => { 
 
    let filteredItems = jsonData.items.filter(item => item.model === modelData.model); 
 
    if (filteredItems.length) { 
 
     acc.push(...filteredItems); 
 
    } 
 
    return acc; 
 
    }, []) 
 

 
console.log(newArray);

+0

謝謝man :)我可以知道'[]'在reduce函數的末尾做了什麼嗎? – 1033

+0

嗯,這是一個更乾淨的解決方案,但是您在每次迭代時都運行「過濾器」,這是IMO詳盡無遺的。 – Umair

+1

@ 1033永遠歡迎。 '[]'是'acc'的初始值,如果省略則是可選的,那麼'acc'的第一個值將是'jsonData.models'的第一個元素。 –

2

我將採取略有不同的方法。我想你可能會喜歡它。

const models = [ 
 
     { 
 
     "model": "ruie9", 
 
     "year": 1998 
 
     }, 
 
     { 
 
     "model": "not-found", 
 
     "year": 1991 
 
     }, 
 
     { 
 
     "model": "aqu0d", 
 
     "year": 1994 
 
     }, 
 
     { 
 
     "model": "ddebd", 
 
     "year": 1995 
 
     }, 
 
     { 
 
     "model": "odq76", 
 
     "year": 1999 
 
     } 
 
    ]; 
 
    
 
    const items = [ 
 
     { 
 
     "model": "ooc0d", 
 
     "code": "2x4qr", 
 
     "price": 33 
 
     }, 
 
     { 
 
     "model": "ruie9", 
 
     "code": "2f6gi", 
 
     "price": 22 
 
     }, 
 
     { 
 
     "model": "aqu0d", 
 
     "code": "2f6gi", 
 
     "price": 21 
 
     }, 
 
     { 
 
     "model": "ddebd", 
 
     "code": "2f6gi", 
 
     "price": 25 
 
     }, 
 
     { 
 
     "model": "ddebd", 
 
     "code": "2f6gi", 
 
     "price": 29 
 
     } 
 
    ]; 
 
    
 
    
 
    
 
    const transformed = models.reduce((res, val) => { 
 
     res[val.model] = val; 
 
     
 
     return res; 
 
    }, {}); // Transform models into a dictionary. 
 
    
 
    
 
    const filtered = items.filter(i => i.model in transformed); 
 
    
 
    console.log(filtered);

+0

謝謝男人:)這是我見過的最好的一個。 – 1033

+0

@ 1033很高興我能幫到你。 – Umair

+1

此外,通過使用這種方法,您只需循環一次「模型」列表,而不必在每次迭代中循環遍歷它。 – Umair

2

你可以這樣做:

我想你想從models陣列添加今年也。 如果是這樣,看看這個實現。這比您之前嘗試的解決方案更有效率O(n)O(n*n)更有效。對於大型陣列O(n*n)不是優選的。

let items = [{ 
 
    "model": "ooc0d", 
 
    "code": "2x4qr", 
 
    "price": 33 
 
    }, 
 
    { 
 
    "model": "ruie9", 
 
    "code": "2f6gi", 
 
    "price": 22 
 
    }, 
 
    { 
 
    "model": "aqu0d", 
 
    "code": "2f6gi", 
 
    "price": 21 
 
    }, 
 
    { 
 
    "model": "ddebd", 
 
    "code": "2f6gi", 
 
    "price": 25 
 
    }, 
 
    { 
 
    "model": "ddebd", 
 
    "code": "2f6gi", 
 
    "price": 29 
 
    } 
 
]; 
 

 
let models = [ 
 
    { 
 
    "model": "ruie9", 
 
    "year": 1998 
 
    }, 
 
    { 
 
    "model": "ooc0d", 
 
    "year": 1991 
 
    }, 
 
    { 
 
    "model": "aqu0d", 
 
    "year": 1994 
 
    } 
 
]; 
 

 
let objModels = models.reduce(function(r,v) { 
 
r[v.model] = v; 
 
return r; 
 
}, {}); 
 

 
let objItems = items.reduce(function(r,v) { 
 
r[v.model] = v; 
 
return r; 
 
}, {}); 
 

 
let ans = []; 
 
for(let key in objItems) { 
 
    if(key in objModels) { 
 
    let o = objItems[key]; 
 
    o.year = objModels[key].year; 
 
    ans.push(o); 
 
    
 
    } 
 
} 
 

 
console.log(ans);

在你的代碼
+0

你[贏](https://jsfiddle.net/sf5jtru6/)恭喜。 –

+0

太棒了!你能解釋我的解決方案的複雜性是「O(n * n)」嗎? – Umair

+0

@Umair我什麼時候說你是'O(n * n)'?這是給OP的。但是,你的解決方案甚至不是OP所需要的。他也想要「年」。看看OP的'year:models [i] .year'的嘗試解決方案。 –