2

I have an array of person objects, where each person have an array of profiles objects which consist of name and an image url, and a list of addresses objects which consist of lat and long properties, as follows:

var listOfPersons = [{
    addresses : [{lat:11, long:11}, {lat:22, long:22}],
    profile: [{image:"some_url1", name: "peter parker"}]
},
{
    addresses : [{lat:33, long:33}, {lat:44, long:44}],
    profile: [{image:"some_url2", name: "bruce wayne"}]
}];

I need to create a new array of objects, where each new object has an image, long, lat properties, for each set of lat long, as follows:

var expectedResult = [
{
    image:"some_url1",
  lat:11,
  long:11
},
{
    image:"some_url1",
  lat:22,
  long:22
},
{
    image:"some_url1",
  lat:33,
  long:33
},
{
    image:"some_url1",
  lat:44,
  long:44
}
];

What is the shortest way (in terms of writing code) to map\ reduce the first array into the second?

6
  • Fastest operationally? In terms of writing speed? Shortest? Commented Jan 7, 2020 at 15:22
  • In terms of writing speed, thanks for the comment Commented Jan 7, 2020 at 15:22
  • Also, can you have more than one thing in profile? Commented Jan 7, 2020 at 15:23
  • Yes, it is an array, but I will always take the first member Commented Jan 7, 2020 at 15:23
  • Can you have more than one profile in the array, or will the profile array will always only have a single member? Commented Jan 7, 2020 at 15:30

5 Answers 5

3

You can use nested Array.flatMap() with Array.map() to iterate the array/address/profiles, and combine image and lat, long properties into a single object:

const listOfPersons = [{"addresses":[{"lat":11,"long":11},{"lat":22,"long":22}],"profile":[{"image":"some_url1","name":"peter parker"}]},{"addresses":[{"lat":33,"long":33},{"lat":44,"long":44}],"profile":[{"image":"some_url2","name":"bruce wayne"}]}];

const result = listOfPersons.flatMap(o =>
  o.addresses.flatMap(({ lat, long }) => 
    o.profile.map(({ image }) => ({
      image,
      lat,
      long
    }))
  )
);

console.log(result);

If you always use just the 1st profile always, you can remove one level of Array.flatMap():

const listOfPersons = [{"addresses":[{"lat":11,"long":11},{"lat":22,"long":22}],"profile":[{"image":"some_url1","name":"peter parker"}]},{"addresses":[{"lat":33,"long":33},{"lat":44,"long":44}],"profile":[{"image":"some_url2","name":"bruce wayne"}]}];

const result = listOfPersons.flatMap(o =>
  o.addresses.map(({ lat, long }) =>  ({
    image: o.profile[0].image,
    lat,
    long
  }))
);

console.log(result);

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

Comments

2

You can use Array.prototype.reduce() with combined Array.prototype.forEach().

The documentation states for reduce():

The reduce() method executes a reducer function (that you provide) on each element of the array, resulting in a single output value.

I think the following can work for you:

const listOfPersons = [{
    addresses : [{lat:11, long:11}, {lat:22, long:22}],
    profile: [{image:"some_url1", name: "peter parker"}]
},
{
    addresses : [{lat:33, long:33}, {lat:44, long:44}],
    profile: [{image:"some_url2", name: "bruce wayne"}]
}];

const result = listOfPersons.reduce((acc, cur) => {
  cur.addresses.forEach(e => acc.push({ ...e, image: cur.profile[0].image }));   
  return acc;
}, []);

console.log(result);

I hope that helps!

Comments

2

Sinced you asked for shortest in writing code:

var listOfPersons = [{addresses: [{lat:11, long:11}, {lat:22, long:22}],profile: [{image:"some_url1", name: "peter parker"}]},{addresses:lat:33, long:33}, {lat:44, long:44}],profile: [{image:"some_url2", name: "bruce wayne"}]}];

const res = listOfPersons.reduce((r,{addresses:a,profile:[{image}]})=> [...r,...a.map(o=>({image,...o}))],[]);

console.log(res);

Here's with formatting and better variable names:

var listOfPersons = [{
  addresses : [{lat:11, long:11}, {lat:22, long:22}],
  profile: [{image:"some_url1", name: "peter parker"}]
},
{
  addresses : [{lat:33, long:33}, {lat:44, long:44}],
  profile: [{image:"some_url2", name: "bruce wayne"}]
}];


const res = listOfPersons.reduce((acc, { addresses: adr, profile: [{image}] }) =>
  [...acc, ...adr.map(a => ({image, ...a}) )],
[]);


console.log(res);

Comments

1
var listOfPersons = [
  {
    addresses: [{ lat: 11, long: 11 }, { lat: 22, long: 22 }],
    profile: [{ image: "some_url1", name: "peter parker" }]
  },
  {
    addresses: [{ lat: 33, long: 33 }, { lat: 44, long: 44 }],
    profile: [{ image: "some_url2", name: "bruce wayne" }]
  }
];

var expectedResult = listOfPersons.reduce(
  (acc, person) => ([
    ...acc,
    ...person.addresses.map(
      address => ({ ...address, image: person.profile[0].image })
    )
  ]),
  []
)

This will give you what you want assuming you always want the first result from .profile

Comments

0
var listOfPersons = [{
    addresses : [{lat:11, long:11}, {lat:22, long:22}],
    profile: [{image:"some_url1", name: "peter parker"}]
},
{
    addresses : [{lat:33, long:33}, {lat:44, long:44}],
    profile: [{image:"some_url2", name: "bruce wayne"}]
}];


var expectedResult = [];
expectedResult.forEach(person => {
    person.addresses.forEach(address => expectedResult.push({image: person.profile[0].image, ...address}))
});

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.