简体   繁体   中英

Convert JS Array to a nested Object

What is the best way to convert:

['[Title A]','child A','child B', '[Title B]', 'child C', 'child D']

to:

{
  0: {
      'title': 'Title A',
      'children': ['child A', 'child B']
     }
  1: {
       'title': 'Title B',
       'children': ['Child C', 'Child D']
     }
}

I have this so far which checks on the presence of brackets [] and I tried to add this to an object with a dynamic index which increments during a for loop every time a title with brackets is found:

let index = 0;
let listObject = {};
for (const listItem of listItems) {
   const titleValue = listItem.match(/\[(.*?)\]/);
   if (titleValue) {
     ++index;
     listObject[index].title = titleValue[1];
   } else {
     listObject[index].children = [listItem];
   }
}

console.log(listObject);

For the sake of simplicity let's first make an array of objects:

const res = arr.reduce((acc, cur) => {
  const titleValue = cur.match(/\[(.*?)\]/)
  titleValue ?
    acc.push({
      title: cur,
      children: []
    }) :
    acc[acc.length - 1].children.push(cur)

  return acc
}, [])

Now you can use the spread operator to have the nested object :

{...res}

Just updated yours so the logic is sound. Can see what you tried.

Read up on creating new objects and arrays in JS, and when you can add to them.

 let listItems = ['[Title A]', 'child A', 'child B', '[Title B]', 'child C', 'child D']; let index = 0; var listObject = {}; for (const listItem of listItems) { const isTitle = listItem[0] == "[" && listItem[listItem.length - 1] == "]" if (isTitle) { ++index; listObject[index] = { title: listItem.substring(1, listItem.length -1), children: [] //Create Array }; //Create Object } else { listObject[index].children.push(listItem); //Add to children array } } console.log(listObject);

To add on why I used an index lookup, instead of regex,

Run this:

 var testArray = []; var arrayCount = 20000000; var regexMatch = /\\[(.*?)\\]/; for (var i = 0; i < arrayCount; i++) { testArray.push("[" + makeid(Math.round(Math.random() * 10)) + "]") } console.log(testArray.length); var start = new Date(); console.log(start.toString()); for (var i = 0; i < arrayCount; i++) { var testItem = testArray[i]; if (testItem.match(regexMatch)) { } else { } } console.log("regex took " + (new Date().getTime() - start.getTime()) / 1000 + " seconds"); start = new Date(); for (var i = 0; i < arrayCount; i++) { var testItem = testArray[i]; if (testItem[0] === "[" && testItem[testItem.length - 1] === "]") { } else { } } console.log("index lookup took " + (new Date().getTime() - start.getTime()) / 1000 + " seconds"); function makeid(length) { var result = ''; var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; var charactersLength = characters.length; for (var i = 0; i < length; i++) { result += characters.charAt(Math.floor(Math.random() * charactersLength)); } return result; }

I don't know if it's the "best" way, but this is my solution:

 const array = [ "[Title A]", "child A", "child B", "[Title B]", "child C", "child D" ]; let index = -1; const res = array.reduce((acc, curr) => { if (/^\\[[^\\]]+\\]$/.test(curr)) { acc = { ...acc, [++index]: { title: curr.substring(1, curr.length - 1), children: [] } }; } else { acc[index].children = [...acc[index].children, curr]; } return acc; }, {}); console.log(res);

 const array = ['[Title A]','child A','child B', '[Title B]', 'child C', 'child D']; let objToPush = {}; let objToSend = {}; array.map((d) => { if (/^\\[[^\\]]+\\]$/.test(d)) { if (Object.keys(objToPush).length > 0) { objToSend[Object.keys(objToSend).length] = { ...objToPush }; objToPush = {}; } objToPush.title = d.substring(1, d.length - 1); } else { objToPush.children = objToPush.children ? [...objToPush.children, d] : [d] } }); objToSend[Object.keys(objToSend).length] = { ...objToPush }; console.log('objToPush', objToSend);

it worked for me (JSFiddle https://jsfiddle.net/wepbzdfL/48/ )

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