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

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.