V. *_*bor 5 javascript arrays filtering javascript-objects
我正在研究一个问题,我必须将一个对象数组从一个表单分组到另一个表单.
一个例子优于1000字:
var initialData = [
{
house: { id: 1, text: "white" },
room: { id: 1, text: "red" },
price: 2.1
},
{
house: { id: 1, text: "white" },
room: { id: 2, text: "blue" },
price: 3.1
},
{
house: { id: 1, text: "white" },
room: { id: 3, text: "red" },
price: 5.8
},
{
house: { id: 2, text: "black" },
room: { id: 1, text: "yellow" },
price: 9.1
},
{
house: { id: 2, text: "black" },
room: { id: 2, text: "green" },
price: 7.7
},
];
Run Code Online (Sandbox Code Playgroud)
新对象应如下所示:
var finalObject = {
houses: [
{
id: 1, text: "white",
rooms: [
{ id: 1, text: "red", price: "2.1" },
{ id: 2, text: "blue", price: "3.1" },
{ id: 3, text: "red", price: "5.8" }
]
},
{
id: 2, text: "black",
rooms: [
{ id: 1, text: "yellow", price: "9.1" },
{ id: 2, text: "green", price: "7.7" }
]
}
]
};
Run Code Online (Sandbox Code Playgroud)
我必须找到所有房间的独特房屋,并从房间内的初始物品中添加每个价格.
我想知道哪个是最好的方法,因为我会有大量的元素?
我有一些关于多个循环的想法,但对我而言,我的解决方案似乎有点过于复杂.
更新:我的问题与复制的候选人不同,因为我不使用lodash,我的对象必须重构一点,而不仅仅是重新组合.
可能的解决方案(灵感来自@ Gael的回答)
finalObject = {}
for (var i = 0; i < initialData.length; ++i) {
var item = initialData[i];
var id = item.house.id;
if(!finalObject[id]) {
finalObject[id] = item.house;
finalObject[id].rooms = [];
}
var room = item.room;
room.price = item.price;
finalObject[id].rooms.push(room);
}
console.log(finalObject);
Run Code Online (Sandbox Code Playgroud)
Array#reduce与辅助对象一起使用:
var initialData = [{"house":{"id":1,"text":"white"},"room":{"id":1,"text":"red"},"price":2.1},{"house":{"id":1,"text":"white"},"room":{"id":2,"text":"blue"},"price":3.1},{"house":{"id":1,"text":"white"},"room":{"id":3,"text":"red"},"price":5.8},{"house":{"id":2,"text":"black"},"room":{"id":1,"text":"yellow"},"price":9.1},{"house":{"id":2,"text":"black"},"room":{"id":2,"text":"green"},"price":7.7}];
var dict = {}; // helper object
var result = initialData.reduce(function(houses, obj) { // reduce the data
var house = dict[obj.house.id]; // get the house from the dict by id
if(!house) { // if house wasn't found
house = Object.assign({}, obj.house, { rooms: [] }); // create a new house object
houses.push(house); // push it into the array of houses
dict[house.id] = house; // add it to the dict by id
}
house.rooms.push(obj.room); // push the room to the current house
return houses;
}, []);
console.log(result);Run Code Online (Sandbox Code Playgroud)
您还可以使用 ES6 Map 和 spread 语法来实现它:
const initialData = [{"house":{"id":1,"text":"white"},"room":{"id":1,"text":"red"},"price":2.1},{"house":{"id":1,"text":"white"},"room":{"id":2,"text":"blue"},"price":3.1},{"house":{"id":1,"text":"white"},"room":{"id":3,"text":"red"},"price":5.8},{"house":{"id":2,"text":"black"},"room":{"id":1,"text":"yellow"},"price":9.1},{"house":{"id":2,"text":"black"},"room":{"id":2,"text":"green"},"price":7.7}];
const result = [...initialData.reduce((houses, { house, room }) => { // reduce the data to a Map
const currentHouse = houses.get(house.id) || Object.assign({}, house, { rooms: [] }); // get the current house from the map by id, or create a new one
currentHouse.rooms.push(room); // push the room to the current house
return houses.set(currentHouse.id, currentHouse); // set the house to the map, and return it
}, new Map()).values()]; // get the values of the map and spread to an array
console.log(result);Run Code Online (Sandbox Code Playgroud)