2

I have 2 arrays. one of them(config) decides how many elements are going to be pushed in new array(finalData) from existing array(items).

I tried to use slice but at the 3rd index the value is duplicated from the 2nd index. Try to run code and you'll get the idea. Here's my sandbox

Desired output is that I get an array of arrays split exactly by using config indexes.

const config = [1,2,1, 2];
const items = ["one", "two", "three", "four", "five", "six", "seven", "eight"];

const finalData = []

for (let i = 0; i < items.length; i++) {
  if(config[i] !== undefined) { 
  finalData.push(items.slice(i, config[i] + i))
  } else {
    finalData.push([items[i]])
  }
}

console.log(finalData);
.as-console-wrapper { max-height: 100% !important; }

10
  • 2
    Could you clarify your desired output? Should it be [ ['one'], ['two', 'three'], ['four'] ... ] or [ ['one'], ['two', 'three'], ['three'] ... ] or something else? Your current code seems to output the second option Commented Sep 20, 2022 at 13:51
  • 1
    for (let i = 0; i < items.length; i += config[i] ?? 1) { ?? Commented Sep 20, 2022 at 13:55
  • @lucasvw yes, that's right, first one. Commented Sep 20, 2022 at 13:55
  • @JohnnyMopp that works, could you please spot my mistake and explain how your solution works? Commented Sep 20, 2022 at 13:58
  • 1
    When you add more than 1 item using slice(), you need to increment i by that number of items. Commented Sep 20, 2022 at 13:59

3 Answers 3

2

I would suggest iterating through the config array instead of the items array

const config = [1, 2, 1, 2];
const items = ["one", "two", "three", "four", "five", "six", "seven", "eight"];

const finalData = [];
let index = 0;
for (let size of config) {
  finalData.push(items.slice(index, index + size));
  index += size;
}
// then collect any remaining
while (index < items.length) {
  finalData.push([ items[index++] ]);
}

console.log(JSON.stringify(finalData));

If the length items can be shorter than the defined config, you may need to add some checks in to prevent empty arrays from being added to final data

Sign up to request clarification or add additional context in comments.

2 Comments

thanks, could you please explain why you did index += size; instead of just index++. I don't fully understand the logic behind this and it only works if we increment with size.
@JeetViramgama size is how many elements we're adding in the current iteration and index is the current location in the items array. So for each iteration, we want to move our index by the number of elements we added during that iteration
1

You can use map() with splice() to get the items from items array with the amount config provides.

If after the map, there are still items in the items array, use another map() to add those

const config = [1,2,1, 2];
const items = ["one", "two", "three", "four", "five", "six", "seven", "eight"];

let finalData = config.map(n => items.splice(0, n))

if (items.length > 0) {
  finalData = [ ...finalData, ...items.map(i => [ i ]) ];
}

console.log(finalData);
.as-console-wrapper { max-height: 100% !important; }

[
  [
    "one"
  ],
  [
    "two",
    "three"
  ],
  [
    "four"
  ],
  [
    "five",
    "six"
  ],
  [
    "seven"
  ],
  [
    "eight"
  ]
]

Comments

1

You could iterate through config array and use .splice(0, qty). Since .splice() mutates the array, if it called on every iteration, the first parameter is 0 index by default.

Details are commented in example

const group = [1, 2, 1, 2];
const items = ["one", "two", "three", "four", "five", "six", "seven", "eight"];

// >ext< = 8 - [1 + 2 + 1 + 2] /* returns 2 */
const ext = items.length - group.reduce((sum, add) => sum + add);

// >cfg< = [1, 2, 1, 2] merge with [1, 1]
const cfg = group.concat(Array(ext).fill(1));

// >qty< = [1, 2, 1, 2, 1, 1] returns [["one"], ["two", "three"],...]
const dat = cfg.flatMap(qty => [items.splice(0, qty)]);

console.log(dat);
.as-console-wrapper { max-height: 100% !important; }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.