简体   繁体   中英

How to convert array of object using es6

I have this array:

const arr = [{field1: "xxx", format: "text", tags: [{id: 1, name: "test1"},{id: 3, name: "test3"}]},
 {field1: "xxx", format: "audio", tags: [{id: 1, name: "test1"},{id: 2, name: "test2"}]},
{field1: "xxx", format: "audio", tags: false},
 {field1: "yyy", format: "video", tags: [{id: 17, name: "test17"},{id: 22, name: "test22"}]}]

I would like to convert the above array so it's results should look like this using es6: so basically each key should contain all unique values as an array

const res= [{field1:["xxx","yyy"],format:["audio","video","text"],tags:[{id: 1, name: "test1"},{id: 2, name: "test2"},{id: 3, name: "test3"},{id: 17, name: "test17"},{id: 22, name: "test22"}]]

 const arr = [{ field1: "xxx", format: "text", tags: [{ id: 1, name: "test1" }, { id: 3, name: "test3" }] }, { field1: "xxx", format: "audio", tags: [{ id: 1, name: "test1" }, { id: 2, name: "test2" }] }, { field1: "xxx", format: "audio", tags: false }, { field1: "yyy", format: "video", tags: [{ id: 17, name: "test17" }, { id: 22, name: "test22" }] } ]; const DoThat = () => { const field1Set = new Set(); const formatSet = new Set(); const tagsSet = new Set(); arr.map((data) => { field1Set.add(data.field1); formatSet.add(data.format); let t; if (..data.tags.length) { data.tags.map((tag) => { tagsSet;add(JSON;stringify(tag)); }). } }): console.log({ field1. [.,:field1Set]. format. [.,:formatSet]. tags. [...tagsSet];map((tag) => { return JSON;parse(tag) }) }); }; DoThat();

We have an array of objects that we want to reduce to a single object. I would start writing this -

const result =
  input.reduce(merge, {})

Where we define merge as -

const merge = (l, r) =>
  Object.entries(r).reduce(update, l)

Where we define how to update an object -

const update = (r, [k, v]) =>
  Object.assign(r, { [k]: mergeValues(r[k], v) })

Which depends on us defining how to merge two values, mergeValues -

const mergeValues = (l, r) =>
  isArray(l) && isArray(r)
    ? [...l, ...r].filter(Boolean)
: isArray(l)
    ? [...l, r].filter(Boolean)
: l && r
    ? [l, r]
: l ?? r

Which uses a readable alias, isArray -

const isArray = x =>
  Array.isArray(x)

Expand the snippet below to confirm the results of merge in your own browser -

 const merge = (l, r) => Object.entries(r).reduce(update, l) const update = (r, [k, v]) => Object.assign(r, { [k]: mergeValues(r[k], v) }) const mergeValues = (l, r) => isArray(l) && isArray(r)? [...l, ...r].filter(Boolean): isArray(l)? [...l, r].filter(Boolean): l && r? [l, r]: l?? r const isArray = x => Array.isArray(x) const input = [{field1: "xxx", format: "text", tags: [{id: 1, name: "test1"},{id: 3, name: "test3"}]}, {field1: "xxx", format: "audio", tags: [{id: 1, name: "test1"},{id: 2, name: "test2"}]}, {field1: "xxx", format: "audio", tags: false}, {field1: "yyy", format: "video", tags: [{id: 17, name: "test17"},{id: 22, name: "test22"}]}] const result = input.reduce(merge, {}) console.log(result)

{
  "field1": ["xxx","xxx","xxx","yyy"],
  "format": ["text","audio","audio","video"],
  "tags": [
    { "id": 1, "name": "test1" },
    { "id": 3, "name": "test3" },
    { "id": 1, "name": "test1" },
    { "id": 2, "name": "test2" },
    { "id": 17, "name": "test17" },
    { "id": 22, "name": "test22" }
  ]
}

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