Have data that has this kind of structure:
$input = [ { animal: 'cat', name: 'Rocky', value: 1 },
{ animal: 'cat', name: 'Spot', value: 2 },
{ animal: 'dog', name: 'Spot', value: 3 } ];
Need fastest possible method for converting to this format:
$output = { animal: [ 'cat', 'dog' ],
name: [ 'Rocky', 'Spot' ],
value: [ 1, 2, 3 ] };
The output should have keys equal to each of the keys in each object from the input. And the output values should be arrays with the sorted unique values. I found a few ways to do it using nested loops, but slower than I would like. With 30,000 elements to the input array with 8 keys for each of the objects, the best I have been able to do is 300ms in Chrome. Would like to get down to 100ms. Is there any faster method using a map or reduce?
Here's one way.
$input = [ { animal: 'cat', name: 'Rocky', value: 1 },
{ animal: 'cat', name: 'Spot', value: 2 },
{ animal: 'dog', name: 'Spot', value: 3 } ];
$output = {animal:{},name:{},value:{}};
$input.forEach(function(v,i) {
$output.animal[v.animal] = 1;
$output.name[v.name] = 1;
$output.value[v.value] = 1;
});
$output.animal = Object.keys($output.animal);
$output.name = Object.keys($output.name);
$output.value = Object.keys($output.value);
It prevents having to test each Array every time. You can performance compare to see if it helps.
live example: http://jsfiddle.net/TJVtj/1/
If you don't want to hardcode the keys, you can make the solution generic.
var keys = Object.keys($input[0]),
$output = {};
keys.forEach(function(v) {
$output[v] = {};
});
$input.forEach(function(v) {
keys.forEach(function(vv) {
$output[vv][v[vv]] = 1;
});
});
keys.forEach(function(v) {
$output[v] = Object.keys($output[v]);
});
live example: http://jsfiddle.net/TJVtj/2/
Warning. All the values will be strings since they're fetched as object keys.
Yet another way for modern browsers:
$input.reduce(function(acc, obj) {
Object.keys(obj).forEach(function(k) {
acc[k] = (acc[k] || []).concat(obj[k])
})
return acc
},{})
function inArray(needle, haystack) {
var length = haystack.length;
for(var i = 0; i < length; i++) {
if(haystack[i] == needle) return true;
}
return false;
}
Above function is used to check duplicates
$output={};
for(i=0; i< $input.length; i++)
{
if(!$output.animal) $output.animal=[];
if(!$output.name) $output.name=[];
if(!$output.value) $output.value=[];
var ani=$input[i];
if(ani.animal && !inArray(ani.animal, $output.animal)) $output.animal.push(ani.animal);
if(ani.name && !inArray(ani.name, $output.name)) $output.name.push(ani.name);
if(ani.value) $output.value.push(ani.value);
}
// If you don't know the objects all have the same keys you need to look at each one-
var output= {},
input= [{
animal:'cat', name:'Rocky', value:1
},{
animal:'cat', name:'Spot', value:2
},{
animal:'dog', name:'Spot', value:3
}];
input.forEach(function(itm){
for(var p in itm){
if(itm.hasOwnProperty(p)){
if(!output[p]) output[p]= [];
if(output[p].indexOf(itm[p])== -1) output[p].push(itm[p]);
}
}
});
Run.expose(output)// nonstandard object to string method
// returned value: (String)
{
animal:[
'cat',
'dog'
],
name:[
'Rocky',
'Spot'
],
value:[
1,
2,
3
]
}
试试Underscore ,这种任务非常棒)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.