Home > front end >  Group an array of objects into a new array each time a specific value is found
Group an array of objects into a new array each time a specific value is found

Time:07-15

Is it possible to group an array of objects into a new array each time a specific value is found?

In this case, every time "type" equals "divider" all objects till then, need to be added to a new array.

Current JSON Object:

[
    {
        "type": "type-a",
        "name": "Foo"
    },
    {
        "type": "type-b",
        "name": "Foo"
    },
    {
        "type": "type-c",
        "name": "Foo"
    },
    {
        "type": "divider",
        "name": "Foo"
    },
    {
        "type": "type-b",
        "name": "Foo"
    },
    {
        "type": "type-b",
        "name": "Foo"
    },
    {
        "type": "divider",
        "name": "Foo"
    },
    {
        "type": "type-c",
        "name": "Foo"
    }
]

How I would like my new JSON Object to look like:

[
    [
        {
            "type": "type-a",
            "name": "Foo"
        },
        {
            "type": "type-b",
            "name": "Foo"
        },
        {
            "type": "type-c",
            "name": "Foo"
        }
    ],
    [
        {
            "type": "type-b",
            "name": "Foo"
        },
        {
            "type": "type-b",
            "name": "Foo"
        }
    ],
    [
        {
            "type": "type-c",
            "name": "Foo"
        }
    ]
]

CodePudding user response:

This should work

const arr = [{ "type": "type-a", "name": "Foo" }, { "type": "type-b", "name": "Foo" }, { "type": "type-c", "name": "Foo" }, { "type": "divider", "name": "Foo" }, { "type": "type-b", "name": "Foo" }, { "type": "type-b", "name": "Foo" }, { "type": "divider", "name": "Foo" }, { "type": "type-c", "name": "Foo" }];

function divide(container, divider) {
  const final = [];
  let tmp = new Array();
  for (let item of container) {
    if (item.type === divider) {
      final.push(tmp);
      tmp = new Array();
    }
    item.type !== divider && tmp.push(item)
  }

  tmp.length > 0 && final.push(tmp)
  return final;
}

const res = divide(arr, 'divider');

console.log(res)

CodePudding user response:

You can make use of reduce here as:

const arr = [{ "type": "type-a", "name": "Foo" }, { "type": "type-b", "name": "Foo" }, { "type": "type-c", "name": "Foo" }, { "type": "divider", "name": "Foo" }, { "type": "type-b", "name": "Foo" }, { "type": "type-b", "name": "Foo" }, { "type": "divider", "name": "Foo" }, { "type": "type-c", "name": "Foo" }];

const temp = [];
const result = arr.reduce((acc, curr) => {
  if (curr.type === 'divider') {
    acc.push([...temp]);
    temp.length = 0;
  } else {
    temp.push(curr);
  }
  return acc;
}, []);
if (temp.length) result.push([...temp]);

console.log(result);
/* This is not a part of answer. It is just to give the output full height. So IGNORE IT */
.as-console-wrapper { max-height: 100% !important; top: 0; }

CodePudding user response:

Try this. Search each object of the array and till you find the divider one, push all the objects into another array.

If divider is found, then increment the index, ignore this object and continue.

let arr=[{"type":"type-a","name":"Foo"},{"type":"type-b","name":"Foo"},{"type":"type-c","name":"Foo"},{"type":"divider","name":"Foo"},{"type":"type-b","name":"Foo"},{"type":"type-b","name":"Foo"},{"type":"divider","name":"Foo"},{"type":"type-c","name":"Foo"}]

let finalArr = []
let currentIndex = 0;

for (let obj of arr) {
  if (obj.type === 'divider') {
    currentIndex  ;
  } else {
    (finalArr[currentIndex] = finalArr[currentIndex] || []).push(obj);
  }
}

console.log(finalArr)

  • Related