简体   繁体   中英

add elements to object - javascript

I'm trying to build an object given an array of objects

const someArray = [
  {
    name: 'x.y',
    value: 'Something for Y'
  },
  {
    name: 'x.a.z',
    value: 'Something for Z'
  }
]

to look like this

{ 
  x: { 
    a: { 
        z: 'Something for Z' 
    },
    y: 'Something for Y' 
  } 
}

I have this code

const buildObj = data => {
  let obj = {}
  
  data.forEach(item => {
      let items = item.name.split('.')
      items.reduce((acc, val, idx) => {
        acc[val] = (idx === items.length - 1) ? item.value : {}
        return acc[val]
      }, obj)
  })

  return obj
}

buildObj(someArray)

but it doesn't include the y keypair. what's missing?

What you want to do is create an object, then for each dotted path, navigate through the object, creating new object properties as you go for missing parts, then assign the value to the inner-most property.

 const someArray = [{"name":"xy","value":"Something for Y"},{"name":"xaz","value":"Something for Z"}] const t1 = performance.now() const obj = someArray.reduce((o, { name, value }) => { // create a path array const path = name.split(".") // extract the inner-most object property name const prop = path.pop() // find or create the inner-most object const inner = path.reduce((i, segment) => { // if the segment property doesn't exist or is not an object, // create it if (typeof i[segment] !== "object") { i[segment] = {} } return i[segment] }, o) // assign the value inner[prop] = value return o }, {}) const t2 = performance.now() console.info(obj) console.log(`Operation took ${t2 - t1}ms`)
 .as-console-wrapper { max-height: 100% !important; }

Here's an option using for loops and checking nesting from the top down.

 const someArray = [ { name: 'x.y', value: 'Something for Y' }, { name: 'xaz', value: 'Something for Z' } ] function parseArr(arr) { const output = {}; for (let i = 0; i < arr.length; i++) { const {name, value} = arr[i]; const keys = name.split('.'); let parent = output; for (let j = 0; j < keys.length; j++) { const key = keys[j]; if (!parent.hasOwnProperty(key)) { parent[key] = j === keys.length - 1 ? value : {}; } parent = parent[key]; } } return output; } console.log(parseArr(someArray));

This is ABD at this point but I did it with a recursive builder of the path.

 const someArray = [ { name: 'x.y', value: 'Something for Y' }, { name: 'xaz', value: 'Something for Z' } ] const createPath = (path, value) => { if(path.length === 1){ let obj = {} obj[path.shift()] = value return obj } let key = path.shift(); let outObject = {} outObject[key] = { ...createPath(path, value) } return outObject } const createObjectBasedOnDotNotation = (arr) => { let outObject = {} for(let objKey in arr){ const { name, value } = arr[objKey]; let object = createPath(name.split("."), value) let mainKey = Object.keys(object)[0]; !outObject[mainKey] ? outObject[mainKey] = {...object[mainKey]} : outObject[mainKey] = { ...outObject[mainKey], ...object[mainKey] } } return outObject } console.log(createObjectBasedOnDotNotation(someArray))

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