1

I have an Array like this

[
    {
        name: "A",
        job: ["1", "2"]
    },
    {
        name: "B",
        job: ["2"]
    },
    {
        name: "C",
        job: []
    }
]

How do i flatten it into something like this using lodash.

[
    {
        name: "A",
        job: ["1"]
    },
    {
        name: "A",
        job: ["2"]
    },
    {
        name: "B",
        job: ["2"]
    },
    {
        name: "C",
        job: []
    }
]

The only solution coming to my mind is to iterate recursively.

Thanks.

2
  • Is there any specific reason why you want to use lodash for this problem? It's a problem that can very easily be solved using native javascript functions. Commented Mar 12, 2019 at 11:11
  • Hey @LarsHoldaas, The reason i preferred lodash over VanillaJS is because if in future the nesting has sub nests then lodash is better capable of handling it. At least it's what i thought based on normal lodash capabilities. Commented Mar 12, 2019 at 11:22

3 Answers 3

2

You don't need to use recursion if your object isn't multiple levels deep.

Instead, you can achieve this without lodash and recursion. You could use .flatMap to get each job array, and then create an individual object for each item within that job array using .map.

See example below:

const arr = [{name: "A", job: ["1", "2"]}, {name: "B", job: ["2"]}, {name: "C", job: []}];

const spreadArrObj = arr => {
  return arr.flatMap(({name, job}) => {
    if(job.length < 2) return {name, job}; // if the object is empty or has one one object then return the object
    return job.map(elem => ({ // map each element in the job array to its own object
      name,
      job: [elem]
    }));
  });
}

console.log(spreadArrObj(arr));

See browser compatibility for .flatMap here.

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

2 Comments

Thank you. I am using lodash's _.flatMap() so i guess it won't be a problem on the backend.
@Nithin no worries :), yeah, that should work fine then
1

let arr = [{
    name: "A",
    job: ["1", "2"]
  },
  {
    name: "B",
    job: ["2"]
  },
  {
    name: "C",
    job: []
  }
];
let newArr = [];
for (i = 0; i < arr.length; i++) {
  var job = arr[i].job
  if (job.length > 0) {
    for (j = 0; j < job.length; j++) {
      obj = {};
      obj.name = arr[i].name;
      obj.job = [job[j]];
      newArr.push(obj);
    }
  } else {
    obj = {};
    obj.name = arr[i].name;
    obj.job = [];
    newArr.push(obj);
  }
}
console.log(newArr);

1 Comment

Thank you. This is how i had implemented earlier.
1

You can use array reduce and check length of job array. If it is more than 1 then iterate the job array and create a new object and push it to the accumulator

let data = [{
    name: "A",
    job: ["1", "2"]
  },
  {
    name: "B",
    job: ["2"]
  },
  {
    name: "C",
    job: []
  }
]

let newData = data.reduce(function(acc, curr) {
  if (curr.job.length > 1) {
    curr.job.forEach(function(item) {
      acc.push({
        name: curr.name,
        job: [item]
      })

    })
  } else {
    acc.push(curr)

  }
  return acc;
}, []);
console.log(newData)

1 Comment

Thank you @brk, This solution also works and we can use it regardless of having lodash. It's just that Nick answered first and my question also had lodash requirement satisfied.

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.