Separate an array into groups?

Asked

Viewed 5,283 times

6

I have the code below answered by a question similar to this but I would like to upgrade, this is the current function:

function separar(base, maximo) {
  var resultado = [[]];
  var grupo = 0;

  for (var indice = 0; indice < base.length; indice++) {
    if (resultado[grupo] === undefined) {
      resultado[grupo] = [];
    }

    resultado[grupo].push(base[indice]);

    if ((indice + 1) % maximo === 0) {
      grupo = grupo + 1;
    }
  }

  return resultado;
}

Such a function will separate a common array into a multidimensional group according to the number of keys per group that is specified in maximo, but now I need a function similar to the same one but with the following change:

The last key of the previous group should be the first of the next group to be generated.

For example:

var meuArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
/*separo meu array em grupos de 3 chaves*/
console.log(separar(meuArray, 3));

The example above should print:

   [
      0: [1, 2, 3]
      1: [4, 5, 6]
      2: [7, 8, 9]
      3: [10]
   ]

With the change I would like you to print the array as follows:

   [
      0: [1, 2, 3]
      1: [3, 4, 5]
      2: [5, 6, 7]
      3: [7, 8, 9]
      4: [9, 10, 1]
   ]

In the last group I already include the first key of the next group, how can I do this?

  • 1

    how it would look if var meuArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]; and if var meuArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];

  • The penultimate group in the case would be [9, 10, 11] and the last would be [11, 1]

  • If you had 12 keys the penultimate would be [9, 10, 11] and the last would be [11, 12, 1]

4 answers

8


You can optimize the function a little using Array#Slice.

Upshot:

function separar(base, max) {
  var res = [];
  
  for (var i = 0; i < base.length; i = i+(max-1)) {
    res.push(base.slice(i,(i+max)));
  }
  res[res.length-1].push(base[0]);
  return res;
}

var meuArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
/*separo meu array em grupos de 3 chaves*/
console.log(separar(meuArray, 3));
.as-console-wrapper {top: 0; max-height: 100%!important}

The idea is to "cut" the array by parts, but if the group is not the first cut from the previous index with respect to the current position and finally add the first index of the source array to the last of the result array.

  • By optimizing, you say improve the performance and speed with which my function returns a result compared to my current?

  • 1

    I mean the amount of code @Leoletto

  • 3

    Surely the best answer +1

  • 1

    @Guilhermelautert Best response with the best time +1

  • As a curiosity regarding performance @Leoletto: jsPerf

  • Thank you @Lucascosta

Show 1 more comment

2

With few modifications, it is possible to arrive at the expected result:

function separar(base, maximo) {
  var resultado = [[]];
  var grupo = 0;
  var ultimo_valor = 0;

  for (var indice = 0; indice < base.length; indice++) {

    if (resultado[grupo] === undefined) {
      resultado[grupo] = [];
      // ultimo valor passa a ser o primero da nova linha
      resultado[grupo].push(ultimo_valor);
    }

    resultado[grupo].push(base[indice]);

    ultimo_valor = base[indice];

    if ((resultado[grupo].length) % maximo === 0) {
      grupo = grupo + 1;
    }

  }

  // adiciona ultimo elemento que vai apontar para o primeiro novamente
  if (typeof resultado[grupo] == 'undefined') {
      resultado[grupo] = [ultimo_valor, base[0]];
  } else if (resultado[grupo].length < maximo) {
      resultado[grupo].push(base[0]);
  } else {
      if (typeof resultado[grupo + 1] == 'undefined') {
         resultado[grupo + 1] = [ultimo_valor, base[0]];
      } else {
         resultado[grupo + 1].push(base[0]);  
      }
  }
  return resultado;

}

2

You can check if each group has the right size and inside this if make the whole logic to change group and start the new already with the first element.

A suggestion could be so:

function separar(base, maximo) {
  var resultado = [[]];
  var grupo = 0;

  for (var indice = 0; indice < base.length; indice++) {
    resultado[grupo].push(base[indice]);

    if (resultado[grupo].length === maximo) {
      grupo++;
      if (indice + 1 < base.length) resultado[grupo] = [base[indice]];
    }
  }

  return resultado;
}
var meuArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

console.log(separar(meuArray, 3));

0

function separar(arr, len){
    var r = [], i = 0, last;
    r[i] = []; 
    do{
        do{
            r[i].push(last = arr.shift() || r[0][0]);
        }while(r[i].length < len);
        if(arr.length >0){
            r[i++] = [];
            r[i].push(last);
        }
    }while(arr.length != 0);

    return r;
}


var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
console.log(separar(arr, 3));

arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
console.log(separar(arr, 3));

Browser other questions tagged

You are not signed in. Login or sign up in order to post.