Home > Net >  Splitting an array into multiple parts?
Splitting an array into multiple parts?

Time:12-01

Given a 2D array I am looking for an elegant and performant way to divide up a 1D array of words given a start index and end index.

// pass this in as an arg
var trim = [
  [3, 4], // remove two words at index 3 and 4
  [9, 10] // remove two words at index 9 and 10
]; // use this to reformat

var words = [
  { word: "hello", st: 0 },
  { word: "stack-overflow", st: 0.5 },
  { word: "lets", st: 1 },
  { word: "remove", st: 1.5 },
  { word: "some", st: 2 },
  { word: "words", st: 2.5 },
  { word: "efficiently", st: 3 },
  { word: "lets", st: 3.5 },
  { word: "do", st: 4 },
  { word: "it", st: 4.5 },
  { word: "yay", st: 5 }
];

// this is the result I am looking for
var result = [
  [
    { word: "hello", st: 0 },
    { word: "stack-overflow", st: 0.5 },
    { word: "lets", st: 1 }
  ],
  [
    { word: "words", st: 2.5 },
    { word: "efficiently", st: 3 },
    { word: "lets", st: 3.5 },
    { word: "do", st: 4 }
  ]
];

This is the best I could do, missing return as 2D array

words.reduce((acc, curr, i) => {
    const wordBetween = trim.some(t => {
        return t[0] <= i && t[1] >= i
    });

    console.log({wordBetween, curr})

    if (wordBetween) {
        return acc;
    }
    
    return [...acc, curr]
}, [])

CodePudding user response:

Pure elegance! And supreme performance! Jokes aside, this should convey the idea.

let start = 0;
let result = [];
for (let [end, newStart] of trim) {
  result.push(words.slice(start, end));
  start = newStart   1;
}
result.push(words.slice(start, words.length));

Note that 2 splits results in three chunks ( n splits give n 1 chunks ) so there might be an empty array at the start or end. This has precedence in string.split.

CodePudding user response:

we can make uses of JSON.stringify to split up the objects.

const splitArrayBasedOnIndexes = (arr = [], indexToRemove = []) => {
    indexToRemove = indexToRemove.flat(Infinity);
    let result = JSON.stringify(arr.map((w, i) => {
        if (indexToRemove.includes(i)) return null;
        return w
    }))
    result = result.substring(1, result.lastIndexOf("]")).split("null").reduce((p, c) => {
        if (c.substring(c.indexOf("{"), c.lastIndexOf("}")   1))
            p.push(JSON.parse("["   c.substring(c.indexOf("{"), c.lastIndexOf("}")   1)   "]"))
        return p
    }, []);

    return result;
}

const words = [
    { word: "hello", st: 0 },
    { word: "stack-overflow", st: 0.5 },
    { word: "lets", st: 1 },
    { word: "remove", st: 1.5 },
    { word: "some", st: 2 },
    { word: "words", st: 2.5 },
    { word: "efficiently", st: 3 },
    { word: "lets", st: 3.5 },
    { word: "do", st: 4 },
    { word: "it", st: 4.5 },
    { word: "yay", st: 5 }
];

const trim = [
    [3, 4],
    [9, 10]
];

console.log(splitArrayBasedOnIndexes(words, trim));

CodePudding user response:

Here's a way to filter an array, removing some specified indexes...

const arrayWithoutIndexes = (array, indexes) => {
  return array.filter((el, i) => !indexes.includes(i));
};

var words = [
  { word: "hello", st: 0 },
  { word: "stack-overflow", st: 0.5 },
  { word: "lets", st: 1 },
  { word: "remove", st: 1.5 },
  { word: "some", st: 2 },
  { word: "words", st: 2.5 },
  { word: "efficiently", st: 3 },
  { word: "lets", st: 3.5 },
  { word: "do", st: 4 },
  { word: "it", st: 4.5 },
  { word: "yay", st: 5 }
];

console.log(arrayWithoutIndexes(words, [1,4]));

EDIT: To handle several sets of indexes, producing a new set of edited words for each set of indexes, just map that function over the index input...

const arrayWithoutIndexes = (array, indexes) => {
  // the map here just copies the word, so the result has new word objects
  return array.filter((el, i) => !indexes.includes(i)).map(o => Object.assign({}, o));
};

var words = [
  { word: "hello", st: 0 },
  { word: "stack-overflow", st: 0.5 },
  { word: "lets", st: 1 },
  { word: "remove", st: 1.5 },
  { word: "some", st: 2 },
  { word: "words", st: 2.5 },
  { word: "efficiently", st: 3 },
  { word: "lets", st: 3.5 },
  { word: "do", st: 4 },
  { word: "it", st: 4.5 },
  { word: "yay", st: 5 }
];

let removeThese = [
  [2, 3],
  [4, 5]
];

let result = removeThese.map(indexes => arrayWithoutIndexes(words, indexes));
console.log(result)

  • Related