Mardzis Mardzis - 1 month ago 5
Javascript Question

Convert JS array to objects

I have a problem with the correct converting array to the form what I need from a graph plugin. I have a

JSON
which looks like below, from this file I have to count how many titles I have (see pic. 1). Hope you will understand from the pictures.

[
{
"name": "Mike Frost",
"title": "value_1",
"gender": "Male"
},
{
"name": "Hans Karl",
"title": "value_6",
"gender": "Male"
},
{
"name": "Kelly Clarkson",
"title": "value_3",
"gender": "Female"
},
...
]


This what I've got so far:

enter image description here

This what I need:

enter image description here

There is my script which counts values from
JSON
.

var employeeData = require('json!../path/to/json.json');
var obj = [];
for (var i = 0, j = employeeData.length; i < j; i++) {
if (obj[employeeData[i]['title']]) {
obj[employeeData[i]['title']]++;
}
else {
obj[employeeData[i]['title']] = 1;
}
}

Answer

One convenient way to do this is with a map (either a real Map if you're using ES2015, or an object we're using as a map if you're using ES5 or earlier). You build a new array and also keep track of the array entries in the map keyed by the value_X value:

var json = '[' +
'  {' +
'    "name": "Mike Frost",' +
'    "title": "value_1",' +
'    "gender": "Male"' +
'  },' +
'  {' +
'    "name": "Hans Karl",' +
'    "title": "value_6",' +
'    "gender": "Male"' +
'  },' +
'  {' +
'    "name": "Another Six",' +
'    "title": "value_6",' +
'    "gender": "Male"' +
'  },' +
'  {' +
'    "name": "Kelly Clarkson",' +
'    "title": "value_3",' +
'    "gender": "Female"' +
'  },' +
'  {' +
'    "name": "Another 3",' +
'    "title": "value_3",' +
'    "gender": "Female"' +
'  },' +
'  {' +
'    "name": "Yet Another 3",' +
'    "title": "value_3",' +
'    "gender": "Female"' +
'  }' +
']';

// Parse the JSON
var data = JSON.parse(json);

// The new array we'll build
var newArray = [];

// Our "map"
var map = Object.create(null);

// Loop the parsed data
data.forEach(function(entry) {
    // Get the existing new entry if any
    var mapEntry = map[entry.title];
    if (mapEntry) {
        // We have one, increase its `value`
        ++mapEntry.value;
    } else {
        // There isn't one, create it with a count of 1
        // and save it to the array
        mapEntry = map[entry.title] = {
            label: entry.title,
            value: 1
        };
        newArray.push(mapEntry);
    }
});

// Done
console.log(newArray);

That can be written much more concisely, but I wanted to call out the individual parts of what I was doing.

In ES2015+:

const json = `[
  {
    "name": "Mike Frost",
    "title": "value_1",
    "gender": "Male"
  },
  {
    "name": "Hans Karl",
    "title": "value_6",
    "gender": "Male"
  },
  {
    "name": "Another Six",
    "title": "value_6",
    "gender": "Male"
  },
  {
    "name": "Kelly Clarkson",
    "title": "value_3",
    "gender": "Female"
  },
  {
    "name": "Another 3",
    "title": "value_3",
    "gender": "Female"
  },
  {
    "name": "Yet Another 3",
    "title": "value_3",
    "gender": "Female"
  }
]`;

// Parse the JSON
const data = JSON.parse(json);

// The new array we'll build
const newArray = [];

// Our map
const map = new Map();

// Loop the parsed data
data.forEach(entry => {
    // Get the existing new entry if any
    let mapEntry = map.get(entry.title);
    if (mapEntry) {
        // We have one, increase its `value`
        ++mapEntry.value;
    } else {
        // There isn't one, create it with a count of 1
        // and save it to the array
        mapEntry = {
            label: entry.title,
            value: 1
        };
        map.set(entry.title, mapEntry);
        newArray.push(mapEntry);
    }
});

// Done
console.log(newArray);