0

[NOTE: though similar to this stack question, my question differers significantly (IMO) due to the different structures of the initial variables. Mine is an array, the other questioner's is an object. My array contains nested objects/arrays, the latter of which contain name-value pairs whose values are, unlike the pairs in the other questioner's, not semantically identified.]

I have one big array (arr1) containing 24 objects. Each of the 24 objects contains one object, and one array of six further objects, like so:

var arr1 =
[
{'hour':1,'car':[{'audi':1377},{'bmw':716},{'ford':3819},{'mazda':67},{'toyota':11580},{'tesla':0}]},
{'hour':2,'car':[{'audi':1340},{'bmw':709},{'ford':3420},{'mazda':28},{'toyota':11583},{'tesla':0}]},
...etc, up to hour 24
];

As you can see, each of the 24 objects represents one hour's worth of data on car models and mileage. (What is NOT obvious is that the numeric value in each of the six objects represents miles.)

Now, I want to convert each object in arr1 into one array containing six objects, like below. So Hour 1's data in arr1 would convert to:

var arr2 = [{"car":"audi","miles":1377},{"car":"bmw","miles":716},{"car":"ford","miles":3819},{"car":"mazda","miles":67},{"car":"toyota","miles":11580},{"car":"tesla","miles":0}];

How can I do this? I have tried the following:

var hourx = 1;
var hour = arr1[hourx-1];
var car=hour.car;
    for(var hourx1=0;hourx1<car.length;hourx1++){
    var xx = car[hourx1];
    var newobj = [];
    for (var value in xx) {
    var chartvar = newobj.push({car:value,miles:xx[value]});
    var arr2 = newobj;
}
    }

... but if I console.log(arr2); it only gives one array of one object.

I'm stumped. Anybody have an idea how I could accomplish this?

Community
  • 1
  • 1
prokaryote
  • 437
  • 6
  • 16
  • Possible duplicate of [Access / process (nested) objects, arrays or JSON](http://stackoverflow.com/questions/11922383/access-process-nested-objects-arrays-or-json) – Teemu Feb 01 '16 at 17:03
  • You are only getting one element in the array as you are initializing newobj array within the loop, so it keeps being reset. Take the `var newobj = [];` outside the loop to fix this. – Rebecka Feb 01 '16 at 17:15
  • @Michael, that did it. Gosh, I stared at that so long I didn't see it. Thanks so much. And thanks to all the others who offered suggestions, I love the Stack! – prokaryote Feb 01 '16 at 17:46

4 Answers4

2

So you want to have an array of arrays as a final result?

var arr1 = [
    {'hour':1,'car':[{'audi':1377},{'bmw':716},{'ford':3819},{'mazda':67},{'toyota':11580},{'tesla':0}]},
    {'hour':2,'car':[{'audi':1340},{'bmw':709},{'ford':3420},{'mazda':28},{'toyota':11583},{'tesla':0}]}
];

var arr2 = arr1.map(function(hour){
    return hour.car.map(function(car){
      var carName = Object.keys(car)[0];
      return {
          "car": carName,
        "miles": car[carName]
      }
  })
})

https://jsfiddle.net/1jjzeeyz/

Bragolgirith
  • 2,167
  • 2
  • 24
  • 44
1

Try using .map() , Object.keys()

var arr1 = [{
  'hour': 1,
  'car': [{
    'audi': 1377
  }, {
    'bmw': 716
  }, {
    'ford': 3819
  }, {
    'mazda': 67
  }, {
    'toyota': 11580
  }, {
    'tesla': 0
  }]
}, {
  'hour': 2,
  'car': [{
    'audi': 1340
  }, {
    'bmw': 709
  }, {
    'ford': 3420
  }, {
    'mazda': 28
  }, {
    'toyota': 11583
  }, {
    'tesla': 0
  }]
}];

var hours = arr1.map(function(cars, index) {
  var carNames = Object.keys(cars.car);
  var names = carNames.map(function(c) {
    var name = Object.keys(cars.car[c])[0];
    var res = {};
    res["car"] = name;
    res["miles"] = cars.car[c][name];
    return res
  })
  return names
})
console.log(hours)
guest271314
  • 1
  • 15
  • 104
  • 177
0

You would have to iterate over the array. Get the first property (let's hope it stays this way). Then get it value. Then create an object and add it to the array. See fiddle here

var arr1 =
[
   {'hour':1,'car':[{'audi':1377},{'bmw':716},{'ford':3819},{'mazda':67},{'toyota':11580},{'tesla':0}]},
   {'hour':2,'car':[{'audi':1340},{'bmw':709},{'ford':3420},{'mazda':28},{'toyota':11583},{'tesla':0}]},
];

var arr = [];
for (var i = 0; i< arr1[0].car.length; i++){
    var car = arr1[0].car[i];
  var key = Object.keys(car)[0];
  arr.push({
    car: key,
    miles: car[key]
  });
}
Peter Rasmussen
  • 16,474
  • 7
  • 46
  • 63
0

a combination of reduce and map will help. /example:

var
  arr1 =[
    {'hour':1,'car':[{'audi':1377},{'bmw':716},{'ford':3819},{'mazda':67},{'toyota':11580},{'tesla':0}]},
    {'hour':2,'car':[{'audi':1340},{'bmw':709},{'ford':3420},{'mazda':28},{'toyota':11583},{'tesla':0}]}
  ],
  arr2 = arr1.reduce(function (collector, item) {

    collector.push(item.car.map(function (car/*, idx, list*/) {
      var
        make  = Object.keys(car)[0]
      ;
      return {
        "car"   : make,
        "miles" : car[make]
      }
    }));
    return  collector;

  }, [])
;
console.log("arr2 : ", arr2);
Peter Seliger
  • 11,747
  • 3
  • 28
  • 37
  • of course vtosh did provide the best / most comprehensive solution. Solving the task does not need `reduce` at all, `map` twice already does it. – Peter Seliger Feb 01 '16 at 18:31