Home > database >  JavaScript — Split an array like a string
JavaScript — Split an array like a string

Time:07-15

Is it possible to split an array into smaller arrays each time a specific value is found? In this case, every time type equals "divider".

Input:

[
    {
        "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"
    }
]

Desired output:

[
    [
        {
            "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)

CodePudding user response:

Here's a curried recursive function:

The first parameter is a predicate function that takes an element and decides whether that element is a delimiter. Then it takes an array and splits it into chunks. Each chunk contains the elements in between (but excluding) a delimiter element.

const splitBy = pred => function loop([x, ...xs], ret = [[]]) {
  if (x == null) return ret;
  if (pred(x)) ret.push([]);
  else ret[ret.length-1].push(x);
  return loop(xs, ret);
}

const isDivider = x => x.type == 'divider';
const splitByDivider = splitBy(isDivider);

splitByDivider([ { "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" }]);

//=> [ [ { "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" } ]]
  • Related