我有一个称为存储的对象数组:
stores = [
{
storeId: 1,
city: "San Francisco",
state: "CA",
},
{
storeId: 2,
city: "Seattle",
state: "WA",
},
{
storeId: 3,
city: "Vancouver",
state: "BC",
},
{
storeId: 4,
city: "Los Angeles",
state: "CA",
},
]
和另一个称为item的对象数组:
items = [
{
itemId: 1,
cost: 10,
price: 20,
sold: false,
_storeId: 1,
},
{
itemId: 2,
cost: 10,
price: 20,
sold: false,
_storeId: 1,
},
{
itemId: 3,
cost: 5,
price: 12,
sold: true,
_storeId: 2,
},
{
itemId: 4,
cost: 12,
price: 20,
sold: false,
_storeId: 3,
},
{
itemId: 5,
cost: 2,
price: 10,
sold: false,
_storeId: 4,
},
{
itemId: 6,
cost: 10,
price: 50,
sold: true,
_storeId: 4,
},
]
我想按商店汇总以下类别:
然后按商店计数总项目数:
然后计算商店出售的小计商品:
所以我的最终存储阵列看起来像这样:
storesUpdated = [
{
storeId: 1,
city: "San Francisco",
state: "CA",
totalCost: 20,
totalPrice: 40,
countTotalItems: 2,
countSoldItems: 0
},
{
storeId: 2,
city: "Seattle",
state: "WA",
totalCost: 5,
totalPrice: 12,
countTotalItems: 1,
countSoldItems: 1
},
{
storeId: 3,
city: "Vancouver",
state: "BC",
totalCost: 12,
totalPrice: 20,
countTotalItems: 1,
countSoldItems: 0
},
{
storeId: 4,
city: "Los Angeles",
state: "CA",
totalCost: 12,
totalPrice: 60,
countTotalItems: 2,
countSoldItems: 1
},
]
我尝试过映射到商店数组,但是卡在这里:
const storesUpdated = stores.map((store) => {
= {}
items.forEach(item => {
if (item._storeId === store.storeId) {
return totalCost {
'storeId' : item.storeId,
}
}
})
})
有什么想法吗?非常感谢。
答案 0 :(得分:1)
const stores = [{storeId:1,city:"San Francisco",state:"CA",},{storeId:2,city:"Seattle",state:"WA",},{storeId:3,city:"Vancouver",state:"BC",},{storeId:4,city:"Los Angeles",state:"CA",},]
const items = [{itemId:1,cost:10,price:20,sold:!1,_storeId:1,},{itemId:2,cost:10,price:20,sold:!1,_storeId:1,},{itemId:3,cost:5,price:12,sold:!0,_storeId:2,},{itemId:4,cost:12,price:20,sold:!1,_storeId:3,},{itemId:5,cost:2,price:10,sold:!1,_storeId:4,},{itemId:6,cost:10,price:50,sold:!0,_storeId:4,},]
const storesUpdated = stores.map((store) => {
const updatedStore = { ...store,
totalCost: 0,
totalPrice: 0,
countTotalItems: 0,
countSoldItems: 0
}
items.forEach(item => {
if (item._storeId === store.storeId) {
updatedStore.totalCost += item.cost
updatedStore.totalPrice += item.price
updatedStore.countTotalItems += 1
updatedStore.countSoldItems += item.sold ? 1 : 0
}
})
return updatedStore
})
console.log(storesUpdated)
答案 1 :(得分:0)
如果只想循环遍历数据,则可以分两步执行合并:
创建“空”存储并通过id在单个reduce中对其进行索引:(在stores
上循环一次)
const Store = (data) => ({ /* ... */ });
const storesById = storeData => storeData.reduce(
(map, sd) => Object.assign(map, { [sd.storeId]: Store(sd) }),
{}
);
遍历项目并将其合并到相应的商店中:(items
上的一个循环)
const addItemToStoreMap = (storeMap, item) => ({
...storeMap,
[item._storeId]: addItemToStore(storeMap[item._storeId], item)
});
请注意,使用对象散布语法创建所有新对象会抵消性能的提高,但这仍然是O(n + m)而不是O(n * m)还是很不错的。
将它们放在一起:
const storeData = [{storeId:1,city:"San Francisco",state:"CA",},{storeId:2,city:"Seattle",state:"WA",},{storeId:3,city:"Vancouver",state:"BC",},{storeId:4,city:"Los Angeles",state:"CA",},]
const itemData = [{itemId:1,cost:10,price:20,sold:!1,_storeId:1,},{itemId:2,cost:10,price:20,sold:!1,_storeId:1,},{itemId:3,cost:5,price:12,sold:!0,_storeId:2,},{itemId:4,cost:12,price:20,sold:!1,_storeId:3,},{itemId:5,cost:2,price:10,sold:!1,_storeId:4,},{itemId:6,cost:10,price:50,sold:!0,_storeId:4,},]
const { Store, addItemToStoreMap, storesById } = storeUtils();
// Loop over the stores *once*, loop over the items *once*
// During the second loop, add items to the right stores
const itemsByStoreId = itemData.reduce(addItemToStoreMap, storesById(storeData));
console.log(Object.values(itemsByStoreId));
function storeUtils() {
// Our client-side model for a Store
const Store = ({ storeId, city, state }) => ({
storeId,
city,
state,
totalCost: 0,
totalPrice: 0,
countTotalItems: 0,
countSoldItems: 0
});
// Merge logic for adding an item to a store
// Can be used in a reduce on a list of items seeded with a store
const addItemToStore = (store, item) => ({
...store,
totalCost: store.totalCost + item.cost,
totalPrice: store.totalPrice + item.price,
countTotalItems: store.countTotalItems + 1,
countSoldItems: store.countSoldItems + item.sold
});
// Selects the right store for an item and returns a new
// map with the updated store
const addItemToStoreMap = (storeMap, item) => ({
...storeMap,
[item._storeId]: addItemToStore(storeMap[item._storeId], item)
});
// Converts raw data to Store objects and indexes them by their id
const storesById = storeData => storeData.reduce(
(map, sd) => Object.assign(map, { [sd.storeId]: Store(sd) }),
{}
);
return { Store, addItemToStoreMap, storesById };
};