4

So i have an array which stores hobbies for each user in an array within the object..

var hobbies = [
  {
    "id": 1,
    "hobbies": []
  },

  {
    "id": 2,
    "hobbies": [
      "football"
    ]
  },
  {
    "id": 3,
    "hobbies": [
      "football",
      "basketball"
    ]
  }
]

What i want to return is a new array of objects but each hobby separated into their own object like below.

var result = [
  {
    "id": 2,
    "hobby": "football"
  },
 {
    "id": 3,
    "hobby": "football"
  },
 {
    "id": 3,
    "hobby": "basketball"
  }
]

What is have so far is

hobbies.filter((f, i) => f.hobbies.length > 0).map((p, i) => {
    while (i < p.hobbies.length) {
 return { id : p.id, hobby : p.hobbies[i] };
}
  });

which only returns

[
  {
    "id": 2,
    "hobby": "football"
  },
  {
    "id": 3,
    "hobby": "basketball"
  }
]
1
  • By the looks of it you are using a relational approach here. Why? Javascript is not a relational DB, no need to reference foreign ids. Just attach a hobbies property to each user object. Commented Mar 1, 2018 at 11:57

5 Answers 5

1

You can use array#reduce with array#map. Iterate through each object and then iterate through each hobby of hobbies and create the object.

var hobbies = [ { "id": 1, "hobbies": [] }, { "id": 2, "hobbies": [ "football" ] }, { "id": 3, "hobbies": [ "football", "basketball" ] } ],
    result = hobbies.reduce((r, {id, hobbies}) => r.concat(hobbies.map(hobby => ({id, hobby}))), []);
console.log(result);

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

1 Comment

This works well with what I was trying to achieve, thanks.
1

I know, "functional" programming is considered "cool" around these parts, however, have you considered using simple loops to, well, loop over your data?

let result = [];

for (let {hobbies, id} of data)
    for (let hobby of hobbies)
        result.push({id, hobby})

In my opinion, this is far more readable than any reduce spaghetti one could come up with ;)

Comments

0

You need to use inner-loop to loop through the hobbies and push them one-by-one to the target array:

var hobbies = [{
    "id": 1,
    "hobbies": []
  },

  {
    "id": 2,
    "hobbies": [
      "football"
    ]
  },
  {
    "id": 3,
    "hobbies": [
      "football",
      "basketball"
    ]
  }
];

var result = hobbies.reduce((acc, item) => {
  item.hobbies.forEach(hobby => {
    acc.push({
      id: item.id,
      hobby: hobby
    });
  });
  return acc;
}, []);

console.log(result);

Comments

0

You can use array.prototype.reduce:

var hobbies = [{"id": 1,"hobbies": []},{"id": 2,"hobbies": ["football"]},{"id": 3, "hobbies": ["football","basketball"]}];

var res = hobbies.reduce((m, o) => (o.hobbies.forEach(h => m.push({id: o.id, hobby: h})), m), []);

console.log(res);

Comments

0

You need nested loops and this is the basics of it:

You first need to loop over the main hobbies array.

Then for each item in the array (which represents a person), you want to loop through their hobbies, and for each one of those hobbies, you need to push an object made up of the profile ID and the hobby into results array I created earlier.

var hobbies = [{ "id": 1, "hobbies": [] }, { "id": 2, "hobbies": [ "football" ] }, { "id": 3, "hobbies": [ "football", "basketball" ] } ];

let result = [];

hobbies.forEach(function(profile){
  profile.hobbies.forEach(function(hobby){
    result.push(
            {
        "id": profile.id,
        "hobby": hobby
      }
    );
  });
});

console.log(result)

Update: the other answers with Array.reduce (a more specialised loop) will cut the above code down even further.

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.