Search code examples
javascriptarraysjsonsortingcollections

How would I write this reportCandidates' function better?


This is the input data in array named candidatesArray:

[ 
 {"name":"george","languages":["php","javascript","java"],"age":19,"graduate_date":1044064800000,"phone":"32-991-511"},
 {"name":"anna","languages":["java","javascript"],"age":23,"graduate_date":1391220000000,"phone":"32-991-512"},
 {"name":"hailee","languages":["regex","javascript","perl","go","java"],"age":31,"graduate_date":1296525600000,"phone":"32-991-513"}
]

I need to transform in this collection as a result of the function:

{candidates: [
    {name: "George", age: 19, phone: "32-991-511"},
    {name: "Hailee", age: 31, phone: "32-991-513"},
    {name: "Anna", age: 23, phone: "32-991-512"}
],
languages: [
    {lang:"javascript",count:1}, 
    {lang:"java", count:2}, 
    {lang:"php", count:2}, 
    {lang:"regex", count:1}
]}

The function repCandidates:

const reportCandidates = (candidatesArray) => { return repObject}

  • I need to write it in javascript ES6
  • I shouldn't use loops(for, while, repeat) but foreach is allowed and it could be better if I use "reduce" function
  • The candidates should be return by their name, age and phone organized by their graduate_date.
  • The languages should be returned with their counter in alphabetic order .

Visit https://codepen.io/rillervincci/pen/NEyMoV?editors=0010 to see my code, please.


Solution

  • One option would be to first reduce into the candidates subobject, while pushing the langauges of each to an array.

    After iterating, sort the candidates and remove the graduate_date property from each candidate, then use reduce again to transform the languages array into one indexed by language, incrementing the count property each time:

    const input = [{
      "name": "george",
      "languages": ["php", "javascript", "java"],
      "age": 19,
      "graduate_date": 1044064800000,
      "phone": "32-991-511"
    }, {
      "name": "anna",
      "languages": ["java", "javascript"],
      "age": 23,
      "graduate_date": 1391220000000,
      "phone": "32-991-512"
    }, {
      "name": "hailee",
      "languages": ["regex", "javascript", "perl", "go", "java"],
      "age": 31,
      "graduate_date": 1296525600000,
      "phone": "32-991-513"
    }];
    
    
    const output = input.reduce((a, { languages, ...rest }) => {
      a.candidates.push(rest);
      a.languages.push(...languages);
      return a;
    }, { candidates: [], languages: [] });
    
    output.candidates.sort((a, b) => a.graduate_date - b.graduate_date);
    output.candidates.forEach(candidate => delete candidate.graduate_date);
    
    output.languages = Object.values(
      output.languages.reduce((a, lang) => {
        if (!a[lang]) a[lang] = { lang, count: 0 };
        a[lang].count++;
        return a;
      }, {})
    );
    output.languages.sort((a, b) => a.lang.localeCompare(b.lang));
    
    console.log(output);