zaq zaq - 5 months ago 40
Javascript Question

Return objects from an array using nested map operation

The following query transform the

json
data as objects - 1st level
map
(No problem over here - I am expecting the result to be like this)

const customerOptions = () => {
return customersQuery.edges.map(({ node: { id, name } }) => {
return { key: id, text: name, value: id };
});
};


Output
enter image description here

However, if I iterate my
json
data using nested
map
operation I am getting the result as an array of objects - (Here I am expecting to return the data in the same format as the 1st query)

const departmentOptions = () => {
return customersQuery.edges.map(({ node: { departments } }) => {
return departments.map(({ id, name }) => {
return { key: id, text: name, value: id };
});
});
};


enter image description here

What I'm trying to achieve is to return the second level array mapping as a list of object so the final result would be a list of 40 objects.

Sample JSON

{
"data": {
"customersQuery": {
"edges": [
{
"node": {
"id": 20,
"name": "Customer name 20",
"departments": [
{
"id": 39,
"name": "Department name 20"
},
{
"id": 40,
"name": "Department name 20"
}
]
}
},
{
"node": {
"id": 19,
"name": "Customer name 19",
"departments": [
{
"id": 37,
"name": "Department name 19"
},
{
"id": 38,
"name": "Department name 19"
}
]
}
},
{
"node": {
"id": 18,
"name": "Customer name 18",
"departments": [
{
"id": 35,
"name": "Department name 18"
},
{
"id": 36,
"name": "Department name 18"
}
]
}
},
{
"node": {
"id": 17,
"name": "Customer name 17",
"departments": [
{
"id": 33,
"name": "Department name 17"
},
{
"id": 34,
"name": "Department name 17"
}
]
}
},
{
"node": {
"id": 16,
"name": "Customer name 16",
"departments": [
{
"id": 31,
"name": "Department name 16"
},
{
"id": 32,
"name": "Department name 16"
}
]
}
},
{
"node": {
"id": 15,
"name": "Customer name 15",
"departments": [
{
"id": 29,
"name": "Department name 15"
},
{
"id": 30,
"name": "Department name 15"
}
]
}
},
{
"node": {
"id": 14,
"name": "Customer name 14",
"departments": [
{
"id": 27,
"name": "Department name 14"
},
{
"id": 28,
"name": "Department name 14"
}
]
}
},
{
"node": {
"id": 13,
"name": "Customer name 13",
"departments": [
{
"id": 25,
"name": "Department name 13"
},
{
"id": 26,
"name": "Department name 13"
}
]
}
},
{
"node": {
"id": 12,
"name": "Customer name 12",
"departments": [
{
"id": 23,
"name": "Department name 12"
},
{
"id": 24,
"name": "Department name 12"
}
]
}
},
{
"node": {
"id": 11,
"name": "Customer name 11",
"departments": [
{
"id": 21,
"name": "Department name 11"
},
{
"id": 22,
"name": "Department name 11"
}
]
}
},
{
"node": {
"id": 10,
"name": "Customer name 10",
"departments": [
{
"id": 13,
"name": "Department name 10"
},
{
"id": 14,
"name": "Department name 10"
}
]
}
},
{
"node": {
"id": 9,
"name": "Customer name 9",
"departments": [
{
"id": 11,
"name": "Department name 9"
},
{
"id": 12,
"name": "Department name 9"
}
]
}
},
{
"node": {
"id": 8,
"name": "Customer name 8",
"departments": [
{
"id": 19,
"name": "Department name 8"
},
{
"id": 20,
"name": "Department name 8"
}
]
}
},
{
"node": {
"id": 7,
"name": "Customer name 7",
"departments": [
{
"id": 15,
"name": "Department name 7"
},
{
"id": 16,
"name": "Department name 7"
}
]
}
},
{
"node": {
"id": 6,
"name": "Customer name 6",
"departments": [
{
"id": 17,
"name": "Department name 6"
},
{
"id": 18,
"name": "Department name 6"
}
]
}
},
{
"node": {
"id": 5,
"name": "Customer name 5",
"departments": [
{
"id": 9,
"name": "Department name 5"
},
{
"id": 10,
"name": "Department name 5"
}
]
}
},
{
"node": {
"id": 4,
"name": "Customer name 4",
"departments": [
{
"id": 7,
"name": "Department name 4"
},
{
"id": 8,
"name": "Department name 4"
}
]
}
},
{
"node": {
"id": 3,
"name": "Customer name 3",
"departments": [
{
"id": 5,
"name": "Department name 3"
},
{
"id": 6,
"name": "Department name 3"
}
]
}
},
{
"node": {
"id": 2,
"name": "Customer name 2",
"departments": [
{
"id": 3,
"name": "Department name 2"
},
{
"id": 4,
"name": "Department name 2"
}
]
}
},
{
"node": {
"id": 1,
"name": "Customer name 1",
"departments": [
{
"id": 1,
"name": "Department name 1"
},
{
"id": 2,
"name": "Department name 1"
}
]
}
}
]
}
}
}


For reference this is how my GraphQL query looks likeenter image description here

Answer Source

I would make the outer function call a reduce() instead of a map() and concat() or push.apply() the inner map() in the reducer function:

Using concat():

let customersQuery = {"edges":[{"node":{"id":20,"name":"Customer name 20","departments":[{"id":39,"name":"Department name 20"},{"id":40,"name":"Department name 20"}]}},{"node":{"id":19,"name":"Customer name 19","departments":[{"id":37,"name":"Department name 19"},{"id":38,"name":"Department name 19"}]}},{"node":{"id":18,"name":"Customer name 18","departments":[{"id":35,"name":"Department name 18"},{"id":36,"name":"Department name 18"}]}},{"node":{"id":17,"name":"Customer name 17","departments":[{"id":33,"name":"Department name 17"},{"id":34,"name":"Department name 17"}]}},{"node":{"id":16,"name":"Customer name 16","departments":[{"id":31,"name":"Department name 16"},{"id":32,"name":"Department name 16"}]}},{"node":{"id":15,"name":"Customer name 15","departments":[{"id":29,"name":"Department name 15"},{"id":30,"name":"Department name 15"}]}},{"node":{"id":14,"name":"Customer name 14","departments":[{"id":27,"name":"Department name 14"},{"id":28,"name":"Department name 14"}]}},{"node":{"id":13,"name":"Customer name 13","departments":[{"id":25,"name":"Department name 13"},{"id":26,"name":"Department name 13"}]}},{"node":{"id":12,"name":"Customer name 12","departments":[{"id":23,"name":"Department name 12"},{"id":24,"name":"Department name 12"}]}},{"node":{"id":11,"name":"Customer name 11","departments":[{"id":21,"name":"Department name 11"},{"id":22,"name":"Department name 11"}]}},{"node":{"id":10,"name":"Customer name 10","departments":[{"id":13,"name":"Department name 10"},{"id":14,"name":"Department name 10"}]}},{"node":{"id":9,"name":"Customer name 9","departments":[{"id":11,"name":"Department name 9"},{"id":12,"name":"Department name 9"}]}},{"node":{"id":8,"name":"Customer name 8","departments":[{"id":19,"name":"Department name 8"},{"id":20,"name":"Department name 8"}]}},{"node":{"id":7,"name":"Customer name 7","departments":[{"id":15,"name":"Department name 7"},{"id":16,"name":"Department name 7"}]}},{"node":{"id":6,"name":"Customer name 6","departments":[{"id":17,"name":"Department name 6"},{"id":18,"name":"Department name 6"}]}},{"node":{"id":5,"name":"Customer name 5","departments":[{"id":9,"name":"Department name 5"},{"id":10,"name":"Department name 5"}]}},{"node":{"id":4,"name":"Customer name 4","departments":[{"id":7,"name":"Department name 4"},{"id":8,"name":"Department name 4"}]}},{"node":{"id":3,"name":"Customer name 3","departments":[{"id":5,"name":"Department name 3"},{"id":6,"name":"Department name 3"}]}},{"node":{"id":2,"name":"Customer name 2","departments":[{"id":3,"name":"Department name 2"},{"id":4,"name":"Department name 2"}]}},{"node":{"id":1,"name":"Customer name 1","departments":[{"id":1,"name":"Department name 1"},{"id":2,"name":"Department name 1"}]}}]};

const departmentOptions = () => {
  return customersQuery.edges.reduce((result, { node: { departments } }) => {
    return result.concat(departments.map(({ id, name }) => {
      return { key: id, text: name, value: id };
    }));
  }, []);
};

console.log(departmentOptions());

Using push.apply():

let customersQuery = {"edges":[{"node":{"id":20,"name":"Customer name 20","departments":[{"id":39,"name":"Department name 20"},{"id":40,"name":"Department name 20"}]}},{"node":{"id":19,"name":"Customer name 19","departments":[{"id":37,"name":"Department name 19"},{"id":38,"name":"Department name 19"}]}},{"node":{"id":18,"name":"Customer name 18","departments":[{"id":35,"name":"Department name 18"},{"id":36,"name":"Department name 18"}]}},{"node":{"id":17,"name":"Customer name 17","departments":[{"id":33,"name":"Department name 17"},{"id":34,"name":"Department name 17"}]}},{"node":{"id":16,"name":"Customer name 16","departments":[{"id":31,"name":"Department name 16"},{"id":32,"name":"Department name 16"}]}},{"node":{"id":15,"name":"Customer name 15","departments":[{"id":29,"name":"Department name 15"},{"id":30,"name":"Department name 15"}]}},{"node":{"id":14,"name":"Customer name 14","departments":[{"id":27,"name":"Department name 14"},{"id":28,"name":"Department name 14"}]}},{"node":{"id":13,"name":"Customer name 13","departments":[{"id":25,"name":"Department name 13"},{"id":26,"name":"Department name 13"}]}},{"node":{"id":12,"name":"Customer name 12","departments":[{"id":23,"name":"Department name 12"},{"id":24,"name":"Department name 12"}]}},{"node":{"id":11,"name":"Customer name 11","departments":[{"id":21,"name":"Department name 11"},{"id":22,"name":"Department name 11"}]}},{"node":{"id":10,"name":"Customer name 10","departments":[{"id":13,"name":"Department name 10"},{"id":14,"name":"Department name 10"}]}},{"node":{"id":9,"name":"Customer name 9","departments":[{"id":11,"name":"Department name 9"},{"id":12,"name":"Department name 9"}]}},{"node":{"id":8,"name":"Customer name 8","departments":[{"id":19,"name":"Department name 8"},{"id":20,"name":"Department name 8"}]}},{"node":{"id":7,"name":"Customer name 7","departments":[{"id":15,"name":"Department name 7"},{"id":16,"name":"Department name 7"}]}},{"node":{"id":6,"name":"Customer name 6","departments":[{"id":17,"name":"Department name 6"},{"id":18,"name":"Department name 6"}]}},{"node":{"id":5,"name":"Customer name 5","departments":[{"id":9,"name":"Department name 5"},{"id":10,"name":"Department name 5"}]}},{"node":{"id":4,"name":"Customer name 4","departments":[{"id":7,"name":"Department name 4"},{"id":8,"name":"Department name 4"}]}},{"node":{"id":3,"name":"Customer name 3","departments":[{"id":5,"name":"Department name 3"},{"id":6,"name":"Department name 3"}]}},{"node":{"id":2,"name":"Customer name 2","departments":[{"id":3,"name":"Department name 2"},{"id":4,"name":"Department name 2"}]}},{"node":{"id":1,"name":"Customer name 1","departments":[{"id":1,"name":"Department name 1"},{"id":2,"name":"Department name 1"}]}}]};

const departmentOptions = () => {
  return customersQuery.edges.reduce((result, { node: { departments } }) => {
    result.push.apply(result, departments.map(({ id, name }) => {
      return { key: id, text: name, value: id };
    }));
    
    return result;
  }, []);
};

console.log(departmentOptions());

concat() is better if your inner arrays are very large, as it uses heap memory at the downside of copying the data from the result array into a new one each time.

push.apply() is better if your inner arrays are relatively small, as it uses stack memory, and appends the data to the end of the existing result array, and does not perform an explicit copy each time.