1

I have an array of objects something like this

arr = [{"class":"section"},{"fieldGroup":[]},{"class":"col","name":"input"},{"class":"col","name":"dropdown"},{"class":"col","name":"date"},{"fieldGroup":[]},{"class":"col","name":"table"}]

Now I need to move the objects with "class":"col" inside its previous object which contains "fieldGroup"

So my desired output should be like this

arr = [{"class":"section"},{"fieldGroup":[{"class":"col","name":"input"},{"class":"col","name":"dropdown"},{"class":"col","name":"date"}]},{"fieldGroup":[{"class":"col","name":"table"}]}]

I have tried this piece of code

arr.forEach((item: any, index: number) => {
    if (item.class === "col") {
            arr[index - 1].fieldGroup.push(item);
            arr.splice(index, 1);
    }else {
        return arr;
    }
})

but getting an error saying cannot read property push of undefined

any help?

Nick Parsons
  • 45,728
  • 6
  • 46
  • 64
Yaditya
  • 47
  • 7
  • 2
    Use computed property names arr[index - 1][fieldGroup] . Otherwise your are looking for 'fieldGroup' property in your index. – Tushar Shahi Jul 20 '21 at 09:13
  • Does this answer your question? [How to use a computed property name in ES5?](https://stackoverflow.com/questions/32349480/how-to-use-a-computed-property-name-in-es5) – Tushar Shahi Jul 20 '21 at 09:14
  • 1
    Are you 100% certain that objects with `"class":"col"` are _always_ preceded by items with a `fieldGroup` property? The error you're receiving appears to indicate that the object preceding an object with `"class":"col"` doesn't have a `fieldGroup` property. The sample data you provided appears to work correctly. Do you have a sample where it _doesn't_ work? – garbetjie Jul 20 '21 at 09:18
  • _"I need to move the objects with `"class":"col"`"_ - why are other objects like `{"class":"dropdown"}` also moved when they don't have a `class` of `"col"`? – Nick Parsons Jul 20 '21 at 09:18
  • sorry my bad @NickParsons I have edited the code – Yaditya Jul 20 '21 at 09:23
  • Hi @garbetjie I have corrected the code sample now which is giving me an error – Yaditya Jul 20 '21 at 09:24

4 Answers4

2

Your problem is that when you remove an item from your array using .splice() all the items in your arr shift down one index. For example, the item that used to be at index 3 will now be at index 2, the item that used to be at index 4 is will now be at index 3 etc. Your .forEach() loop doesn't take this shift into account, and so once you remove the item at index 2 with .splice() your index changes to 3 for the next iteration, but really, you need to look at index 2 again as your array items have shifted down an index. You can fix this by using a standard for loop and decrementing the index counter when you remove an item to look at th inded again:

const arr = [{"class":"section"},{"fieldGroup":[]},{"class":"col","name":"input"},{"class":"col","name":"dropdown"},{"class":"col","name":"date"},{"fieldGroup":[]},{"class":"col","name":"table"}];

for(let i = 0; i < arr.length; i++) {
  const item = arr[i];
  if (item.class === "col") {
    arr[i - 1].fieldGroup.push(item);
    arr.splice(i, 1);
    i--;
  }
}

console.log(arr);
Nick Parsons
  • 45,728
  • 6
  • 46
  • 64
0
var a = [
  { class: "section" },
  { fieldGroup: [] },
  { class: "col", name: "input" },
  { class: "dropdown" },
  { class: "date" },
  { fieldGroup: [] },
  { class: "col", name: "table" },
];

var res = [];
var currFieldGroup = null;
for (var i in a) {
  if ("fieldGroup" in a[i]) {
    currFieldGroup = a[i];
    res.push(a[i]);
  } else if ("class" in a[i]) {
    if (currFieldGroup) {
      currFieldGroup.fieldGroup.push(a[i]);
    } else {
      res.push(a[i]);
    }
  }
}
console.log(res);
Behemoth
  • 5,389
  • 4
  • 16
  • 40
0

try it ...

   var arr = [{"class":"section","name":"input"},{"fieldGroupName":"one","fieldGroup":[]},{"class":"col","name":"input"},{"class":"col","name":"dropdown"},{"class":"section","name":"input"},{"fieldGroupName":"one","fieldGroup":[]},{"class":"col","name":"date"}]
    
    arr.forEach((elm , index) =>{
     if(elm.class == 'col'){ 
         arr[1].fieldGroup.push(elm) 
         arr.splice(index, 1)
    }
})
    
    console.log(arr);
0

Try this:

var arr = [{
    "class": "section"
  },
  {
    "fieldGroup": []
  },
  {
    "class": "col",
    "name": "input"
  },
  {
    "class": "dropdown"
  },
  {
    "class": "date"
  },
  {
    "fieldGroup": []
  },
  {
    "class": "col",
    "name": "table"
  }
];

let fieldGroupPosition;
let finalArr = [];
let lastGroupPosition = null;

arr.forEach((item, index) => {
  if (Array.isArray(item.fieldGroup)) {
    finalArr.push({
      fieldGroup: []
    });
    lastGroupPosition = finalArr.length - 1;
  } else {
    if (lastGroupPosition)
      finalArr[lastGroupPosition].fieldGroup.push(item);
    else
      finalArr.push(item);
  }
});

console.log(finalArr);
Salvino D'sa
  • 4,018
  • 1
  • 7
  • 19