Home > Blockchain >  Split array of strings into more arrays of strings?
Split array of strings into more arrays of strings?

Time:01-03

Hello so what I want to do is split array of names into more arrays of names and each arrays element joined together should be smaller than specific amount of characters and none of the strings should be split in half. if it needs to be split in half then move it to the next array. so an example would be.

Input: arr: ["george","ben","bob","alex","robert"] amount_of_characters: 10

Output: [["george","ben"],["bob","alex"],["robert"]]

CodePudding user response:

const arr = ["george","ben","bob","alex","robert"];
const amount_of_characters = 10;
const result = [];
let sumChars = 0;

for (let i = 0; i < arr.length; i  ) {
  const word = arr[i];
  
  if (word.length   sumChars > amount_of_characters) {
    result.push([word])
    sumChars = 0;
  }
  else {
    !result.length ? result.push([word]) : result[result.length - 1].push(word);
  }
  
  sumChars  = word.length;
};

console.log(result);

CodePudding user response:

You can easily achieve the result as:

const arr = ['george', 'ben', 'bob', 'alex', 'robert'];
const amount_of_characters = 10;

let currentTotal = 0;
const result = [];

for (let i = 0; i < arr.length; i  ) {
  const curr = arr[i];
  if (currentTotal   curr.length <= amount_of_characters) {
    currentTotal  = curr.length;
    const last = result[result.length - 1];
    !last ? result.push([curr]) : result[result.length - 1].push(curr);
  } else {
    currentTotal = 0;
    result.push([]);
    i--;
  }
}

console.log(result);

CodePudding user response:

function split(arr, amount_of_characters){
  let final_arr = [];
  let i = 0; // This will be used to denote which position on the original array should be filled
  let j = 0; // This will be used to denote which position on the final array should be filled
  while (i < arr.length){
    // Create a new array in the array
    final_arr[j] = [];
    let current_character_count = 0;

    // Iterate over the input array
    while (i < arr.length && arr[i].length   current_character_count < amount_of_characters){
      final_arr[j].push(arr[i]);
      current_character_count  = arr[i].length;
      i  ;
    }
    j  ;
  }
}

CodePudding user response:

You could use a for-of loop and access the last element of the current group using Array.prototype.at():

const groupByUpToNCharacters = (arr, n) => {
    const groups = [[]];
    let currGroupLength = 0;
    for (const word of arr) {
        const wordLength = word.length;
        if (currGroupLength   wordLength <= n) {
            groups.at(-1).push(word);
            currGroupLength  = wordLength;
        } else {
            groups.push([word]);
            currGroupLength = wordLength;
        }
    }
    return groups;
}


const arr = ["george", "ben", "bob", "alex", "robert"];
const groupedArr = groupByUpToNCharacters(arr, 10);
console.log(groupedArr);

CodePudding user response:

So, what is required here is an algorithm to achieve the expected result. While multiple answers above have given elegant solutions, the below solutions use a recursive approach.

Solution - Style-1:

const joinUptoLen1 = (arr = [], mlen, i = 0) => (
  i < arr.length - 1 ?
  arr[i].length   arr[i   1].length < mlen ?
  [
    [arr[i], arr[i   1]]
  ].concat(joinUptoLen1(arr, mlen, i   2)) :
  [
    [arr[i]]
  ].concat(joinUptoLen1(arr, mlen, i   1)) :
  i === arr.length - 1 ?
  [
    [arr[i]]
  ] :
  []
);

The same solution written another way is shown below:

Solution - Style-2:

const joinUptoLen2 = (arr = [], mlen, i = 0) => {
  if (i < arr.length - 1) {
    if (arr[i].length   arr[i   1].length < mlen) {
      return [
        [arr[i], arr[i   1]]
      ].concat(joinUptoLen2(arr, mlen, i   2));
    } else {
      return [
        [arr[i]]
      ].concat(joinUptoLen2(arr, mlen, i   1));
    }
  } else {
    if (i === arr.length - 1) return [
      [arr[i]]
    ];
    return [];
  }
};

Approach is very simple. Check if sum-of-lengths of 2 consequent array-elements is lesser than the input-length. If so, make an array of the 2 elements and push this new-array into the result-array. If not, push an array with just the one element into the result-array. Recursively follow the same and handle the edge-scenario (if the last element was not included into a pair).

And here's a code snippet for quick-demo:

const inpArr1 = ["george", "ben", "bob", "alex", "robert"];
const inpArr2 = ["george", "ben", "bob", "alex", "robert", "pat"];
const splitLen = 10;

const joinUptoLen1 = (arr = [], mlen, i = 0) => (
  i < arr.length - 1 ?
  arr[i].length   arr[i   1].length < mlen ? [
    [arr[i], arr[i   1]]
  ].concat(joinUptoLen1(arr, mlen, i   2)) : [
    [arr[i]]
  ].concat(joinUptoLen1(arr, mlen, i   1)) :
  i === arr.length - 1 ? [
    [arr[i]]
  ] : []
);

const joinUptoLen2 = (arr = [], mlen, i = 0) => {
  if (i < arr.length - 1) {
    if (arr[i].length   arr[i   1].length < mlen) {
      return [
        [arr[i], arr[i   1]]
      ].concat(joinUptoLen2(arr, mlen, i   2));
    } else {
      return [
        [arr[i]]
      ].concat(joinUptoLen2(arr, mlen, i   1));
    }
  } else {
    if (i === arr.length - 1) return [
      [arr[i]]
    ];
    return [];
  }
};

console.log('style-1 results: ', joinUptoLen1(inpArr1, splitLen));
console.log('style-2 results: ', joinUptoLen2(inpArr1, splitLen));

CodePudding user response:

const foo = function (arr, max) { // arr - input, max - max characters in one array
const result = [];
for (let i = 0; i < arr.length; i  ) {
    let cur = [];
    if (arr[i].length < max && i !== arr.length - 1) {
        let sum = arr[i].length;
        cur.push(arr[i]);
        while (sum <= max) {
            i  ;
            if (arr[i].length   sum <= max) {
                sum  = arr[i].length;
                cur.push(arr[i]);
            } else {
                sum = max   1;
                i--;
            }
        }
    } else cur.push(arr[i]);
    result.push(cur);
}
return result;

};

CodePudding user response:

Another way of writing it using Array.reduce():

const input = ["george","ben","bob","alex","Robert"];

let idx=0;

const output = (amount_of_characters)=>{
    return input.reduce((acc,curr)=>{
        acc[idx]?null: acc.push([]);
        acc[idx].join('').length   curr.length <= amount_of_characters? 
        acc[idx].push(curr):(idx  , acc.push([]), acc[idx].push(curr)); 
        return acc;
    },[])
}

console.log(output(10));

  • Related