0

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;
    }
}
0

3 Answers 3

1

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);

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for it, the ES5+ solution is exactly what I was looking for
0

You can use Array.prototype.reduce and a hash table to group the data - see demo below:

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

var result = object.reduce(function(hash){
   return function(prev, curr){
     if(hash[curr.title])
       hash[curr.title].value++;
     else {
       hash[curr.title] = {label: curr.title, value: 1};
       prev.push(hash[curr.title]);
     }
     return prev;
   };
}(Object.create(null)), []);

console.log(result);
.as-console-wrapper{top:0;max-height:100%!important;}

Comments

0

You could iterate the array and count the occurence of the same titles.

var data = [{ "name": "Mike Frost", "title": "value_1", "gender": "Male" }, { "name": "Hans Karl", "title": "value_6", "gender": "Male" }, { "name": "Kelly Clarkson", "title": "value_3", "gender": "Female" }, { "name": "Kelly Clarkson", "title": "value_3", "gender": "Female" }, ],
    result = data.reduce(function (hash) {
        return function (r, a) {
            if (!hash[a.title]) {
                hash[a.title] = { label: a.title, value: 0 };
                r.push(hash[a.title]);
            }
            hash[a.title].value++;
            return r;
        };
    }(Object.create(null)), []);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

ES6 with Map

var data = [{ "name": "Mike Frost", "title": "value_1", "gender": "Male" }, { "name": "Hans Karl", "title": "value_6", "gender": "Male" }, { "name": "Kelly Clarkson", "title": "value_3", "gender": "Female" }, { "name": "Kelly Clarkson", "title": "value_3", "gender": "Female" }, ],
    result = data.reduce(
        (map =>
            (r, a) =>
                (!map.has(a.title) && map.set(a.title, r[r.push({ label: a.title, value: 0 }) - 1]), map.get(a.title).value++, r)
        )(new Map), []);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.