1

I have this array of profile objects being returned by my api:

const profilesData = [
  {
    profile: { id: "26144385", some: "more", other: "misc" },
    photo_details: {
      photos: [{ small: "bar-1", medium: "baz-1" }]
    }
  },
  {
    profile: { id: "26144334", some: "even", other: "some more" },
    photo_details: {
      photos: [
        { small: "bar-2", medium: "baz-2" },
        { small: "fizz-2", medium: "buzz-2" }
      ]
    }
  }
];

I need to transform it so that I get a single profileWithPhotos array looks like this:

const profileWithPhotos = [
  {
    id: "26144385",
    some: "more",
    other: "misc",
    photos: [
      {
        small: "bar-1",
        medium: "baz-1"
      }
    ]
  },
  {
    id: "26144334",
    some: "even",
    other: "some more",
    photos: [
      {
        small: "bar-2",
        medium: "baz-2"
      },
      {
        small: "fizz-2",
        medium: "buzz-2"
      }
    ]
  }
];

So far I have tried breaking up the parsing into smaller functions:

const getProfiles = profilesData =>
  profilesData.map(profileData => profileData.profile);

const getSmallAndMediumPic = pic => ({ small: pic.small, medium: pic.medium });

const getPhotos = profilesData =>
  profilesData.map(profileData => profileData.photo_details.photos.map(getSmallAndMediumPic));

const profiles = getProfiles(profilesData);
const photos = getPhotos(profilesData);

const profileWithPhotos = [...profiles, { photos: photos }];

And now I get this kind of array of objects:

​​​​​[ { id: '26144385', some: 'more', other: 'misc' },​​​​​
​​​​​  { id: '26144334', some: 'even', other: 'some more' },​​​​​
​​​​​  { photos: [ [Object], [Object] ] } ]​​​​​

...which is not what I want.

Here is a working jsbin with the code above

I want to pluck and combine the first extracted collection with the second extracted collection. How do I do this?

7 Answers 7

3

You could use a destructuring assignment and assemple a new object for each element of the array.

const
    profilesData = [{ profile: { id: "26144385", some: "more", other: "misc" }, photo_details: { photos: [{ small: "bar-1", medium: "baz-1" }] } }, { profile: { id: "26144334", some: "even", other: "some more" }, photo_details: { photos: [{ small: "bar-2", medium: "baz-2" }, { small: "fizz-2", medium: "buzz-2" }] } }],
    result = profilesData.map(
        ({ profile: { id, some, other }, photo_details: { photos } }) =>
        ({ id, some, other, photos })
    );

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Or with spread syntax ... for objects on forthcoming JS. This worrks with BABEL.

const
    profilesData = [{ profile: { id: "26144385", some: "more", other: "misc" }, photo_details: { photos: [{ small: "bar-1", medium: "baz-1" }] } }, { profile: { id: "26144334", some: "even", other: "some more" }, photo_details: { photos: [{ small: "bar-2", medium: "baz-2" }, { small: "fizz-2", medium: "buzz-2" }] } }],
    result = profilesData.map(
        ({ profile, photo_details: { photos } }) =>
        ({ ...profile, photos })
    );

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

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

Comments

2

You can do this with some ES6 parameter destructuring and spread syntax in object.

const profilesData = [{"profile":{"id":"26144385","some":"more","other":"misc"},"photo_details":{"photos":[{"small":"bar-1","medium":"baz-1"}]}},{"profile":{"id":"26144334","some":"even","other":"some more"},"photo_details":{"photos":[{"small":"bar-2","medium":"baz-2"},{"small":"fizz-2","medium":"buzz-2"}]}}]

const result = profilesData.map(({profile, photo_details: {photos}}) => {
  return {...profile, photos}
})

console.log(result)

Comments

2

I feel a simple map iteration would do what you want.

const result = profilesData.map(data => {
  return {
    id: data.profile.id,
    some: data.profile.some,
    other: data.profile.other,
    photos: data.photo_details.photos
  }
})
console.log(result);

//result
[{
  id: "26144385",
  other: "misc",
  photos: {
     medium: "baz-1",
     small: "bar-1"
  }],
  some: "more"
}, {
  id: "26144334",
  other: "some more",
  photos: {
     medium: "baz-2",
     small: "bar-2"
  }, {
     medium: "buzz-2",
     small: "fizz-2"
  }],
  some: "even"
}]

Comments

1

I would just loop through the profilesData array and create a new array that reconstructs the object with the attributes you need. Something like..

var data = [];
for(var i=0;i<profilesData.length;i++){
    data[i] = profilesData[i].profile;
    data[i].photos = profilesData[i].photo_details.photos
}
console.log(data);

Comments

1

You can use array#map and array#reduce with Object.assign()

const profilesData = [ { profile: { id: "26144385", some: "more", other: "misc" }, photo_details: { photos: [{ small: "bar-1", medium: "baz-1" }] } }, { profile: { id: "26144334", some: "even", other: "some more" }, photo_details: { photos: [ { small:"bar-2", medium: "baz-2" }, { small: "fizz-2", medium: "buzz-2" } ] } } ],
    result = profilesData.map(o => Object.values(o).reduce((r,o) => Object.assign(r, o), {}));
    
console.log(result);

Comments

1

This is pretty straightforward:

profilesData.map(data => Object.assign({}, data.profile, { photos: data.photo_details.photos }));

Or, if you're only targeting the most recent environments or you're transpiling with e.g. Babel, you can make this even more succinct with parameter destructuring and object spread:

profilesData.map(({profile, photo_details: {photos}}) => ({ ...profile, photos }));

You can see both in action in the below snippet.

const profilesData = [
  {
    profile: { id: "26144385", some: "more", other: "misc" },
    photo_details: {
      photos: [{ small: "bar-1", medium: "baz-1" }]
    }
  },
  {
    profile: { id: "26144334", some: "even", other: "some more" },
    photo_details: {
      photos: [
        { small: "bar-2", medium: "baz-2" },
        { small: "fizz-2", medium: "buzz-2" }
      ]
    }
  }
];

const profilesWithPhotos = profilesData.map(data =>
  Object.assign({}, data.profile, { photos: data.photo_details.photos }));

console.log(profilesWithPhotos);
console.log('-----');

const profilesWithPhotos2 =
  profilesData.map(({profile, photo_details: {photos}}) => ({ ...profile, photos }));

console.log(profilesWithPhotos2);
.as-console-wrapper{min-height:100%}

1 Comment

Note: I added the second bit of code after others had posted very similar answers, but I had not read them at the time I wrote it. Great minds and all that.
0

Well, seems to be late but I think this will work ```

const transformedProfilesData = profilesData.reduce((array, object) => {
  const profile = {...object.profile}
  const photos = object.photo_details.photos.map(photo => photo)
  profile.photos = photos
  array.push(profile)
  return array
}, [])

```

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.