1

I have a JSON array of objects of the format

var employees = 
[
  {
    "employee1": "employee1",
    "Details": [
      {
        "title": "Software Engineer",
        "EmployeeId": 451
      }
    ]
  },
  {
    "employee2": "employee2",
    "Details": []
  },
  {
    "employee3": "employee3",
    "Details": [
      {
        "title": "Test analyst",
        "EmployeeId": 453
      }
    ]
  },
  {
    "employee4": "employee4",
    "Details": [
      {
        "title": "Software engineer",
        "EmployeeId": 487
      },
      {
        "title": "Architect",
        "EmployeeId": 500
      }
    ]
  }
]

What's the best way to get the EmployeeIds?

Expected output:

[451,453,487,500]

When I used:

console.log(Object.assign({}, ...employees).Details.map(t=>t.EmployeeId))

It is returning the result as:

[487,500]

Is there a way to concatenate other employee Ids in the result?

7
  • 1
    first, stop thinking of this as JSON ... it isn't ... it's a javascript object, jSON is a data interchange string format - you'r not dealing with that- do you understand why your attempt didn't work? Commented Mar 20, 2019 at 22:53
  • 2
    employees.map(m => m.Details.map(m => m.EmployeeId)).flat() Commented Mar 20, 2019 at 22:55
  • 1
    @keith - or employees.flatMap(m => m.Details.map(m => m.EmployeeId)) :p Commented Mar 20, 2019 at 22:57
  • @JaromandaX Yeah, flatMap would be better, I kind of kept it at 2 map's to hopefully point the OP in the direction why his failed. Commented Mar 20, 2019 at 23:00
  • @Keith Is there way to find the values without using flatmap or flat? I'm writing this in node version <11 and both functions doesn't work Commented Mar 20, 2019 at 23:02

3 Answers 3

5

Firstly - it's not JSON, just an array. Secondly, use flatMap and map like so:

var employees = [{
    "employee1": "employee1",
    "Details": [{
      "title": "Software Engineer",
      "EmployeeId": 451
    }]
  },
  {
    "employee2": "employee2",
    "Details": []
  },
  {
    "employee3": "employee3",
    "Details": [{
      "title": "Test analyst",
      "EmployeeId": 453
    }]
  },
  {
    "employee4": "employee4",
    "Details": [{
        "title": "Software engineer",
        "EmployeeId": 487
      },
      {
        "title": "Architect",
        "EmployeeId": 500
      }
    ]
  }
];

var ids = employees.flatMap(({ Details }) => Details.map(({ EmployeeId }) => EmployeeId));

console.log(ids);

Polyfill without flatMap - courtesy of MDN's alternative:

var employees = [{
    "employee1": "employee1",
    "Details": [{
      "title": "Software Engineer",
      "EmployeeId": 451
    }]
  },
  {
    "employee2": "employee2",
    "Details": []
  },
  {
    "employee3": "employee3",
    "Details": [{
      "title": "Test analyst",
      "EmployeeId": 453
    }]
  },
  {
    "employee4": "employee4",
    "Details": [{
        "title": "Software engineer",
        "EmployeeId": 487
      },
      {
        "title": "Architect",
        "EmployeeId": 500
      }
    ]
  }
];

var ids = employees.reduce((acc, { Details }) => acc.concat(Details.map(({ EmployeeId }) => EmployeeId)), []);

console.log(ids);

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

6 Comments

Not much browser support for Array.prototype.flatMap() unfortunately ~ developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
@Phil I never worry about that, transpile & polyfill.
It's cool. Just wanted to add a note before you start getting "it says 'flatMap is not a function'"
@Phil I'll add a polyfill to it, don't worry.
Array.prototype.flat() is also not available in Node < 11
|
0

Instead of using flatMap which has questionable support (though I think it's a great answer, mind you) here's an answer that relies on reduce and the spread operator:

employees
  .reduce((a, v) => 
   ( v.Details && a.push(...v.Details.map(o=>o.EmployeeId)), a)
  , []);

without the spread, using flat

employees
  .reduce((a, v) => 
   ( v.Details && a.push(v.Details.map(o=>o.EmployeeId)), a.flat(1))
  , []);

without spread or flat, utilizing [].concat.apply([], arr)

employees
  .reduce((a, v) => 
   ( v.Details && a.push(v.Details.map(o=>o.EmployeeId)), [].concat.apply([], a))
  , []);

Examples of these Working:

var employees=[{employee1:"employee1",Details:[{title:"Software Engineer",EmployeeId:451}]},{employee2:"employee2",Details:[]},{employee3:"employee3",Details:[{title:"Test analyst",EmployeeId:453}]},{employee4:"employee4",Details:[{title:"Software engineer",EmployeeId:487},{title:"Architect",EmployeeId:500}]}];

let _

// setup our methods and name them

( 
array_concat = employees.reduce((a, v) => ( v.Details && a.push(v.Details.map(o=>o.EmployeeId)), [].concat.apply([], a)), [])
)
.name = "Using Array#concat",

(
spread = employees.reduce((a, v) => ( v.Details && a.push(...v.Details.map(o=>o.EmployeeId)), a), [])
)
.name = "Using Spread Operator",

(
flat = employees.reduce((a, v) => ( v.Details && a.push(v.Details.map(o=>o.EmployeeId)), a.flat(1)), [])
)
.name = "Using Flat",



// test if it works!

isCorrect = (arr, json = JSON.stringify(arr), {name} = arr) => 
console.info( json === "[451,453,487,500]" ? `${name} Passed!` : `${name} Failed`);

isCorrect(array_concat);
isCorrect(spread);
isCorrect(flat);

Comments

0

You could try a nested reduce approach. This works quickly and doesn't make use of anything ES5 or higher.

var employees = [{
    "employee1": "employee1",
    "Details": [{
      "title": "Software Engineer",
      "EmployeeId": 451
    }]
  },
  {
    "employee2": "employee2",
    "Details": []
  },
  {
    "employee3": "employee3",
    "Details": [{
      "title": "Test analyst",
      "EmployeeId": 453
    }]
  },
  {
    "employee4": "employee4",
    "Details": [{
        "title": "Software engineer",
        "EmployeeId": 487
      },
      {
        "title": "Architect",
        "EmployeeId": 500
      }
    ]
  }
];

var ids = employees.reduce(function(a, b) {
    return b.Details.reduce(function(c, d) {
        c.push(d.EmployeeId);
        return c;
    }, a);
}, []);

console.log(ids);

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.