我想改变结果的结构。有对象“itemGroup”,我想删除它们并保持键“水果”和“蔬菜”。
[{"id": 1, "shop": "shop1", "itemGroup": {"fruit": 2, "vegetable": 2},"total":4},
{"id": 2, "shop": "shop2", "itemGroup": {"fruit": 0, "vegetable": 1},"total":1}]
我想要这个结果
[
{ "id": 1, "shop": "shop1", "fruit": 2, "vegetable": 2, "total": 4 },
{ "id": 2, "shop": "shop2" "fruit": 0, "vegetable": 1, "total": 1 }
]
我的代码
var myArray = [
{shop: "shop1",item1: "my apple 1",item2: "my carrot 1"},
{shop: "shop1",item1: "my apple 1",item2: "my carrot 1"},
{shop: "shop2",item1: "my apple 0",item2: "my carrot 0"},
{shop: "shop2",item1: "my apple 0",item2: "my carrot 1"}
];
var MyArrayDefinition = [
{item: "my apple 0",color: "red", group: "fruit",score: 0},
{item: "my carrot 1",color: "orange",group: "vegetable",score: 1},
{item: "my apple 1",color: "red", group: "fruit",score: 1},
{item: "my carrot 0",color: "orange",group: "vegetable",score: 0}
];
var k = Object.keys,
items = MyArrayDefinition.reduce((o, v) => (o[v.item] = v, o), {});
var shops = myArray.reduce((o, v, i, s) => (
s = v[k(v).find(k => k)],
s = o[s] || (o[s] = {
fruit: 0,
vegetable: 0,
}),
k(v).forEach(k => k.includes('item') &&
(s[(i = items[v[k]]).group] += i.score)), o), {});
var result = k(shops).map((k, i) => ({
id: i + 1,
shop: k,
itemGroup: shops[k],
total:Object.values(shops[k]).reduce((a, b) => a + b),
}));
答案 0 :(得分:3)
与过去几天的大部分问题非常相似。 :-)
您可以映射数据,使用Object.assign并删除itemGroup。
let x = f.map(e => {
e = Object.assign(e, e.itemGroup);
delete e.itemGroup;
return e;
})
console.log(x);
<script>
let f = [{
"id": 1,
"shop": "shop1",
"itemGroup": {
"fruit": 2,
"vegetable": 2
},
"total": 4
},
{
"id": 2,
"shop": "shop2",
"itemGroup": {
"fruit": 0,
"vegetable": 1
},
"total": 1
}
]
</script>
答案 1 :(得分:0)
使用map是将数据从一个数组转换到另一个数组并在需要时运行计算的方法。
// Create a function that takes in your result array
function setPercentage (array) {
// Helper function that calculates percentage
function percentage (amount, total) {
return (amount / total) * 100
}
// Map the results of the input array onto a new array,
// and return the result
return array.map((obj) => {
return {
id: obj.id,
shop: obj.shop,
fruit: percentage(obj.itemGroup.fruit, obj.total),
vegetable: percentage(obj.itemGroup.vegetable, obj.total),
total: obj.total
}
})
}
// pass in the result array from your code...
const shops_by_percentage = setPercentage(result)
console.log(shops_by_percentage)
/** result in the console.log()
*
[
{
'id': 1,
'shop': 'shop1',
'fruit': 50,
'vegetable': 50,
'total': 4
},
{
'id': 2,
'shop': 'shop2',
'fruit': 0,
'vegetable': 100,
'total': 1
}
]
*
* */
答案 2 :(得分:0)
您可以在下面找到问题的一般解决方案。
使用此方法,您可以在项目数组中创建无限数量的项目,并在定义中创建无限数量的组,您的代码仍将按预期工作。最后,你的分数值作为权重(当你给出一些项目例如得分2时,每次出现将被视为两个项目。)
// Your items
const items = [
{
shop: "shop1",
item1: "my apple 1",
item2: "my carrot 1",
},
{
shop: "shop1",
item1: "my apple 1",
item2: "my carrot 1"
},
{
shop: "shop2",
item1: "my apple 0",
item2: "my carrot 0"
},
{
shop: "shop2",
item1: "my apple 0",
item2: "my carrot 1"
},
];
// Your definitions
const definitions = [
{
item: "my apple 0",
color: "red",
group: "fruit",
score: 0
},
{
item: "my carrot 1",
color: "orange",
group: "vegetable",
score: 1
},
{
item: "my apple 1",
color: "red",
group: "fruit",
score: 1
},
{
item: "my carrot 0",
color: "orange",
group: "vegetable",
score: 0
}
];
function groupShops(items) {
return items.reduce((acc, cur) => {
// Find shop with id of current item in accumulator
const currentShop = acc.find(shop => shop.id === cur.shop);
// Get all shop items
const shopItems = Object.keys(cur)
// Filter shop key as it is shop's ID
.filter(key => key !== 'shop')
// Map keys into values
.map(key => cur[key]);
// If shop already exists in accumulator
if (!!currentShop) {
// Return updated accumulator
return acc
// Remove current shop
.filter(shop => shop !== currentShop)
// And add new copy of current shop with new items to the accumulator
.concat({
id: currentShop.id,
items: currentShop.items.concat(shopItems),
});
}
// If shop doesn't exist in accumulator add it there and return updated accumulator
return acc.concat({
id: cur.shop,
items: shopItems,
});
}, []);
};
function extendItems(shops) {
// Filter items which have score 0 or less
const filterItems = items => items.filter(item => item.score > 0);
// Map though shops
return shops.map(shop => {
// Return updated shop
return {
// Keep shop id
id: shop.id,
// Extend itemIds by the properties stored in the definition and filter them
items: filterItems(shop.items.map(item => definitions.find(definition => definition.item === item))),
}
});
}
function calculateResult(shop, index) {
// Get all available groups
const availableGroups = definitions.reduce((acc, cur) => acc.indexOf(cur.group) > -1 ? acc : acc.concat(cur.group), []);
// Calculate total possible score
const getTotalScore = () => shop.items.reduce((acc, cur) => cur.score + acc, 0);
// Get score of a passed group
const getGroupScore = group => shop.items.reduce((acc, cur) => cur.group === group ? acc + cur.score : acc, 0);
// Loop though each available group and get its score
const resultData = availableGroups.reduce((acc, cur) => {
return {
// Copy data from accumulator
...acc,
// Add new property to the accumulator with a property key {group name} and value {percantage}
[cur]: getGroupScore(cur, shop.items) / getTotalScore(shop.items) * 100,
}
}, {});
// Return result object
return {
// Destruct items of the result object
...resultData,
// Store total items count
total: shop.items.length,
// Store shop id
shop: shop.id,
// Store index
id: index,
}
}
// Groups shops
const groupedShops = groupShops(items);
// Groups shops with extended items
const extendedShops = extendItems(groupedShops);
// You result object
const result = extendedShops.map((shop, index) => calculateResult(shop, ++index));
console.log(result);
&#13;
答案 3 :(得分:0)
阐述您的原始问题&#34;设置商店中每件商品的百分比,并回答您修改后的问题&#34;更改我的数组的结构,这可以通过修改原始代码来实现。
let myArray = [{"shop":"shop1","item1":"my apple 1","item2":"my carrot 1"},{"shop":"shop1","item1":"my apple 1","item2":"my carrot 1"},{"shop":"shop2","item1":"my apple 0","item2":"my carrot 0"},{"shop":"shop2","item1":"my apple 0","item2":"my carrot 1"}]
let MyArrayDefinition = [{"item":"my apple 0","color":"red","group":"fruit","score":0},{"item":"my carrot 1","color":"orange","group":"vegetable","score": null},{"item":"my apple 1","color":"red","group":"fruit","score":1},{"item":"my carrot 0","color":"orange","group":"vegetable","score":0}]
let k = Object.keys
let items = MyArrayDefinition.reduce((o, v) => (o[v.item] = v, o), {})
let shops = myArray.reduce(function (o, v, i, s) {
return s = v[k(v).find(function (k) {
return k;
})], s = o[s] || (o[s] = {
fruit: 0,
vegetable: 0
}), k(v).forEach(function (k) {
return k.includes('item') && (s[(i = items[v[k]]).group] += i.score);
}), o;
}, {});
// Helper function that calculates percentage
function percentage (amount, total) {
if (total === 0) { // added check for 0 divisor
return `0%`
}
return `${(amount / total) * 100}%`
}
let result = k(shops).map((k, i) => {
let total = Object.values(shops[k]).reduce((a, b) => a + b) | 0 // added check if number else 0
let fruit = shops[k].fruit | 0 // added check if number else 0
let veg = shops[k].vegetable | 0 // added check if number else 0
return {
id: i + 1,
shop: k,
fruit: fruit,
vegetable: veg,
total: total,
fruitPercentage: percentage(fruit, total),
vegetablePercentage: percentage(veg, total)
}
})
console.log(JSON.stringify(result, null, 2))
/** result from console.log()
*
[
{
"id": 1,
"shop": "shop1",
"fruit": 2,
"vegetable": 2,
"total": 4,
"fruitPercentage": "50%",
"vegetablePercentage": "50%"
},
{
"id": 2,
"shop": "shop2",
"fruit": 2,
"vegetable": 0,
"total": 2,
"fruitPercentage": "100%",
"vegetablePercentage": "0%"
}
]
* */