![](/img/trans.png)
[英]JavaScript: Create a function groupBy that accepts an array and a callback, and returns an object
[英]JS - Create a callback function that accepts an object returned by the function invoking it
我从这个数据集开始:
var wide_array = [
{
"record": 1,
"associated_location": "Kirrawee",
"identity": "student",
"second_identity": "visitor"
},
{
"record": 2,
"associated_location": "Sutherland",
"identity": "student",
"second_identity": "resident"
},
{
"record": 3,
"associated_location": "Kirrawee",
"identity": "visitor",
"second_identity": "worker"
},
{
"record": 4,
"associated_location": "Miranda",
"identity": "resident",
"second_identity": "worker"
},
{
"record": 5,
"associated_location": "Miranda",
"identity": "student",
"second_identity": ""
},
{
"record": 6,
"associated_location": "Miranda",
"identity": "worker",
"second_identity": "resident"
},
{
"record": 7,
"associated_location": "Sutherland",
"identity": "worker",
"second_identity": "resident"
}
];
然后我想将它从“宽”格式转换为“长”,我可以使用以下方法:
function processData(wide_array) {
const long_array = [];
for (let i = 0; i < wide_array.length; i++) {
const record = wide_array[i];
// Add "identity"
long_array.push({ record: record.record, location: record.associated_location, identity_long: record.identity });
// Add "second_identity"
long_array.push({ record: record.record, location: record.associated_location, identity_long: record.second_identity });
}
return long_array;
}
这给了我:
long_array =
[
{"record":1,"location":"Kirrawee","identity_long":"student"},
{"record":1,"location":"Kirrawee","identity_long":"visitor"},
{"record":2,"location":"Sutherland","identity_long":"student"},
{"record":2,"location":"Sutherland","identity_long":"resident"},
{"record":3,"location":"Kirrawee","identity_long":"visitor"},
{"record":3,"location":"Kirrawee","identity_long":"worker"},
{"record":4,"location":"Miranda","identity_long":"resident"},
{"record":4,"location":"Miranda","identity_long":"worker"},
{"record":5,"location":"Miranda","identity_long":"student"},
{"record":5,"location":"Miranda","identity_long":""},
{"record":6,"location":"Miranda","identity_long":"worker"},
{"record":6,"location":"Miranda","identity_long":"resident"},
{"record":7,"location":"Sutherland","identity_long":"worker"},
{"record":7,"location":"Sutherland","identity_long":"resident"}
];
我想将processData
创建的long_array
对象异步传递到以下addItemCounts
函数中:
groupByKeys = ['location', 'identity'];
function addItemCounts(long_array, groupByKeys) {
var groups = _.groupBy(long_array, obj => {
return groupByKeys.map(key => obj[key]).join('-');
});
return _.map(groups, g => ({
...g[0],
count: g.length
}));
}
grouped_and_counted = addItemCounts(long_array, groupByKeys);
返回:
grouped_and_counted = [
{
"location": "Kirrawee",
"identity_long": "student",
"count": 1
},
{
"location": "Kirrawee",
"identity_long": "visitor",
"count": 2
},
{
"location": "Kirrawee",
"identity_long": "worker",
"count": 1
},
{
"location": "Sutherland",
"identity_long": "student",
"count": 1
},
{
"location": "Sutherland",
"identity_long": "resident",
"count": 2
},
{
"location": "Sutherland",
"identity_long": "worker",
"count": 1
},
{
"location": "Miranda",
"identity_long": "resident",
"count": 2
},
{
"location": "Miranda",
"identity_long": "worker",
"count": 2
},
{
"location": "Miranda",
"identity_long": "student",
"count": 1
},
{
"location": "Miranda",
"identity_long": "",
"count": 1
}
];
我的问题是,如何重写processData
函数以将addItemCounts
作为回调,它将processData
返回的输出和数组( groupByKeys
)作为参数?
在同步上下文中,我会像这样实现我想要的:
// Step one:
intermediary_object = processData(input);
// Step two:
output_object = addItemCounts(intermediary_object, ['location', 'identity']);
但是这不会异步工作,所以我需要重写processData
以将addItemCounts
作为回调函数来异步执行。
异步地,我想要做的看起来更像是以下伪代码:
processData(wide_array, function(long_array, /* returned by processData */
groupByKeys)) /* ... etc */
您可以重写processData
以接受函数addItemCounts
作为它的第二个参数,如下所示:
processData(wide_array, addItemsCounts);
该呼叫后addItemsCounts(long_array, groupByKeys)
从身体后您形成long_array
。
如果您从不同的上下文创建groupByKey
,也可以将它作为processData
的参数。
最终代码
groupByKeys = ['location', 'identity_long'];
function addItemCounts(long_array, groupByKeys) {
var groups = _.groupBy(long_array, obj => {
return groupByKeys.map(key => obj[key]).join('-');
});
return _.map(groups, g => ({
...g[0],
count: g.length
}));
}
function processData(wide_array, addItemsCounts, groupByKeys) {
const long_array = [];
for (let i = 0; i < wide_array.length; i++) {
const record = wide_array[i];
// Add "identity"
long_array.push({ record: record.record, location: record.associated_location, identity_long: record.identity });
// Add "second_identity"
long_array.push({ record: record.record, location: record.associated_location, identity_long: record.second_identity });
}
return addItemsCounts(long_array, groupByKeys);
}
这是大多数接受回调参数的函数的工作方式。
编辑:添加了jsfiddle
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.