使用reduce查询数组中的对象数据并重新格式化
Using reduce to query object data in an array and reformat it
我的数据结构如下所示:
var deliveries = [{
location: "Chicago",
units: 10
}, {
location: "San Francisco",
units: 5
}, {
location: "Miami",
units: 2
}, {
location: "San Francisco",
units: 13
}, {
location: "San Francisco",
units: 2
}, {
location: "Chicago",
units: 16
}, {
location: "Miami",
units: 1
}];
我希望能够查询任何一个城市并获取它们在数据结构中出现的次数以及该城市的单位总数。
我必须执行此操作的代码如下:
function getData(arr, city) {
var numberOfdeliveries = 0;
var totalUnitsDelivered = 0;
arr.forEach(function(val, index, arr) {
if (val.location === city) {
numberOfdeliveries += 1;
totalUnitsDelivered += val.units
}
})
return "number of deliveries: " + numberOfdeliveries + ". Total units:" + totalUnitsDelivered
}
getData(deliveries, "San Francisco"); // number of deliveries: 3. Total units:20
这很好用。
但是,我很好奇是否可以使用 reduce 来 return 一个包含所有城市编号及其所有总单位的数组。
换句话说,最终结果应该是这样的:
[{
"Chicago": 2,
units: 26
}, {
"San Francisco":20,
units: 5
}, {
"Miami": 2,
units: 3
}];
我能得到的最远的是 return 一个包含城市出现次数的对象。
var deliveries = [{
location: "Chicago",
units: 10
}, {
location: "San Francisco",
units: 5
}, {
location: "Miami",
units: 2
}, {
location: "San Francisco",
units: 13
}, {
location: "San Francisco",
units: 2
}, {
location: "Chicago",
units: 16
}, {
location: "Miami",
units: 1
}];
var answer = deliveries.reduce(function(obj, val, index, all) {
if (!obj[val.location]) {
obj[val.location] = 1
} else {
obj[val.location]++
}
return obj
}, {})
console.log(answer); //{ Chicago: 2, 'San Francisco': 3, Miami: 2 }
您可以使用结果数组和散列 table 作为对结果数组中元素的引用。
var deliveries = [{ location: "Chicago", units: 10 }, { location: "San Francisco", units: 5 }, { location: "Miami", units: 2 }, { location: "San Francisco", units: 13 }, { location: "San Francisco", units: 2 }, { location: "Chicago", units: 16 }, { location: "Miami", units: 1 }],
groups = deliveries.reduce(function (hash) {
return function (r, a) {
if (!hash[a.location]) {
hash[a.location] = {};
hash[a.location][a.location] = 0;
hash[a.location].units = 0;
r.push(hash[a.location]);
}
hash[a.location][a.location]++;
hash[a.location].units += a.units;
return r;
};
}(Object.create(null)), []);
console.log(groups);
如果您计划不止一次进行此查询,将您的数据映射到使用城市作为键的散列映射对象会更实用
var cities ={};
deliveries.foreach(function(item){
var cityObj = cities[item.location] ? cities[item.location] :{units:0, count:0}
cityObj.units += item.units;
cityObj.count ++;
});
会产生类似的东西:
{ "Chicago" :{units: 10, count:2},
"San Francisco":{units: 5, count:1}
}
然后当您需要这些值时:
var city="Chicago",
units = cities[city].units;
技术上 Nina 回答了问题,但 charlietfl 我认为使用哈希映射的想法更好(即使 his/her代码似乎不起作用)。所以我想出了如何使用 reduce 创建哈希映射。我把答案给了 Nina 只是因为它是 "correct" 但这是我想出的。
var deliveries = [{
location: "Chicago",
units: 10
}, {
location: "San Francisco",
units: 5
}, {
location: "Miami",
units: 2
}, {
location: "San Francisco",
units: 13
}, {
location: "San Francisco",
units: 2
}, {
location: "Chicago",
units: 16
}, {
location: "Miami",
units: 1
}];
var answer = deliveries.reduce(function(obj, val, index, all) {
if (!obj[val.location]) {
obj[val.location] = {
times: 1,
units: val.units
}
} else {
obj[val.location].times += 1;
obj[val.location].units += val.units;
}
return obj
}, {});
console.log(answer);
您可以使用地图对象进行分组。
var deliveries = [{ location: "Chicago", units: 10 }, { location: "San Francisco", units: 5 }, { location: "Miami", units: 2 }, { location: "San Francisco", units: 13 }, { location: "San Francisco", units: 2 }, { location: "Chicago", units: 16 }, { location: "Miami", units: 1 }, ];
var result = [];
deliveries.reduce(
(cities, delivery) => cities.set(delivery.location, [...(cities.get(delivery.location) || []), delivery]), new Map
).forEach((deliveries, city) => {
var r = {};
r[city] = deliveries.length;
r.units = deliveries.reduce((s, c) => s + c.units, 0);
result.push(r);
})
console.log(result);
我的数据结构如下所示:
var deliveries = [{
location: "Chicago",
units: 10
}, {
location: "San Francisco",
units: 5
}, {
location: "Miami",
units: 2
}, {
location: "San Francisco",
units: 13
}, {
location: "San Francisco",
units: 2
}, {
location: "Chicago",
units: 16
}, {
location: "Miami",
units: 1
}];
我希望能够查询任何一个城市并获取它们在数据结构中出现的次数以及该城市的单位总数。
我必须执行此操作的代码如下:
function getData(arr, city) {
var numberOfdeliveries = 0;
var totalUnitsDelivered = 0;
arr.forEach(function(val, index, arr) {
if (val.location === city) {
numberOfdeliveries += 1;
totalUnitsDelivered += val.units
}
})
return "number of deliveries: " + numberOfdeliveries + ". Total units:" + totalUnitsDelivered
}
getData(deliveries, "San Francisco"); // number of deliveries: 3. Total units:20
这很好用。
但是,我很好奇是否可以使用 reduce 来 return 一个包含所有城市编号及其所有总单位的数组。
换句话说,最终结果应该是这样的:
[{
"Chicago": 2,
units: 26
}, {
"San Francisco":20,
units: 5
}, {
"Miami": 2,
units: 3
}];
我能得到的最远的是 return 一个包含城市出现次数的对象。
var deliveries = [{
location: "Chicago",
units: 10
}, {
location: "San Francisco",
units: 5
}, {
location: "Miami",
units: 2
}, {
location: "San Francisco",
units: 13
}, {
location: "San Francisco",
units: 2
}, {
location: "Chicago",
units: 16
}, {
location: "Miami",
units: 1
}];
var answer = deliveries.reduce(function(obj, val, index, all) {
if (!obj[val.location]) {
obj[val.location] = 1
} else {
obj[val.location]++
}
return obj
}, {})
console.log(answer); //{ Chicago: 2, 'San Francisco': 3, Miami: 2 }
您可以使用结果数组和散列 table 作为对结果数组中元素的引用。
var deliveries = [{ location: "Chicago", units: 10 }, { location: "San Francisco", units: 5 }, { location: "Miami", units: 2 }, { location: "San Francisco", units: 13 }, { location: "San Francisco", units: 2 }, { location: "Chicago", units: 16 }, { location: "Miami", units: 1 }],
groups = deliveries.reduce(function (hash) {
return function (r, a) {
if (!hash[a.location]) {
hash[a.location] = {};
hash[a.location][a.location] = 0;
hash[a.location].units = 0;
r.push(hash[a.location]);
}
hash[a.location][a.location]++;
hash[a.location].units += a.units;
return r;
};
}(Object.create(null)), []);
console.log(groups);
如果您计划不止一次进行此查询,将您的数据映射到使用城市作为键的散列映射对象会更实用
var cities ={};
deliveries.foreach(function(item){
var cityObj = cities[item.location] ? cities[item.location] :{units:0, count:0}
cityObj.units += item.units;
cityObj.count ++;
});
会产生类似的东西:
{ "Chicago" :{units: 10, count:2},
"San Francisco":{units: 5, count:1}
}
然后当您需要这些值时:
var city="Chicago",
units = cities[city].units;
技术上 Nina 回答了问题,但 charlietfl 我认为使用哈希映射的想法更好(即使 his/her代码似乎不起作用)。所以我想出了如何使用 reduce 创建哈希映射。我把答案给了 Nina 只是因为它是 "correct" 但这是我想出的。
var deliveries = [{
location: "Chicago",
units: 10
}, {
location: "San Francisco",
units: 5
}, {
location: "Miami",
units: 2
}, {
location: "San Francisco",
units: 13
}, {
location: "San Francisco",
units: 2
}, {
location: "Chicago",
units: 16
}, {
location: "Miami",
units: 1
}];
var answer = deliveries.reduce(function(obj, val, index, all) {
if (!obj[val.location]) {
obj[val.location] = {
times: 1,
units: val.units
}
} else {
obj[val.location].times += 1;
obj[val.location].units += val.units;
}
return obj
}, {});
console.log(answer);
您可以使用地图对象进行分组。
var deliveries = [{ location: "Chicago", units: 10 }, { location: "San Francisco", units: 5 }, { location: "Miami", units: 2 }, { location: "San Francisco", units: 13 }, { location: "San Francisco", units: 2 }, { location: "Chicago", units: 16 }, { location: "Miami", units: 1 }, ];
var result = [];
deliveries.reduce(
(cities, delivery) => cities.set(delivery.location, [...(cities.get(delivery.location) || []), delivery]), new Map
).forEach((deliveries, city) => {
var r = {};
r[city] = deliveries.length;
r.units = deliveries.reduce((s, c) => s + c.units, 0);
result.push(r);
})
console.log(result);