简体   繁体   中英

JavaScript shortest way to map an array of objects to a new array of new objects?

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?

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);

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!

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);

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

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}))
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM