JavaScript算法练习:Chunky Monkey

Chunky Monkey指的就是把一个数组arr按指定的长度size分割,并且将分割的数组push到一个新数组newArr中,组成一个多维二组。今天这篇文章整理了有关于实现这种效果的方法。

实现原理

创建一个chunk()函数,函数中传入两个参数arrsize,其中arr是要被分割的函数,而size是指分割的长度。然后将分割出来的数组tempArr推入到一个新的数组中newArr

实现这个功能,将会运用到JavaScript中的slice()splice()push()等方法,而且里面还需要配合JavaScript中的forwhile循环。

测试用例

为了能检测chunk()函数功能是否起作用,在写完整个功能后,可以通过下面的测试用例来检测:

  • chunk(["a", "b", "c", "d"], 2) 应该返回 [["a", "b"], ["c", "d"]]
  • chunk([0, 1, 2, 3, 4, 5], 3) 应该返回 [[0, 1, 2], [3, 4, 5]]
  • chunk([0, 1, 2, 3, 4, 5], 2) 应该返回 [[0, 1], [2, 3], [4, 5]]
  • chunk([0, 1, 2, 3, 4, 5], 4) 应该返回 [[0, 1, 2, 3], [4, 5]]
  • chunk([0, 1, 2, 3, 4, 5, 6], 3) 应该返回 [[0, 1, 2], [3, 4, 5], [6]]
  • chunk([0, 1, 2, 3, 4, 5, 6, 7, 8], 4) 应该返回 [[0, 1, 2, 3], [4, 5, 6, 7], [8]]

运用到的相关知识

这里把slice()splice()push()三个方法简单回顾一下,因为后面的方法中常要使用到这三个方法。拿上面的测试用例中的一个来说,假设我们有一个数组arr:

var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8];

另外有一个数组,用来存储临时的数组tempArr还有一个新数组newArr

var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8];
var tempArr = arr.slice(0,4); // [0, 1, 2, 3]
console.log(tempArr);
var newArr = [];
console.log(newArr); // []
newArr.push(tempArr);
console.log(newArr); // [[0, 1, 2, 3]]
console.log(arr); // [0, 1, 2, 3, 4, 5, 6, 7, 8]
tempArr = arr.slice(4, 8);
console.log(tempArr); // [4, 5, 6, 7]
newArr.push(tempArr);
console.log(newArr); // [[0, 1, 2, 3],[4, 5, 6, 7]]
console.log(arr); // [0, 1, 2, 3, 4, 5, 6, 7, 8]
tempArr = arr.slice(8, 12);
console.log(tempArr); // [8]
newArr.push(tempArr);
console.log(newArr); // [[0, 1, 2, 3],[4, 5, 6, 7],[8]]
console.log(arr); // [0, 1, 2, 3, 4, 5, 6, 7, 8]

slice([begin[,end]])会提取原数组中索引从beginend的所有元素。提取出来的元素将存入一个新的数组对象中,并返回这个新的数组。特别注意一点:``slice()`不会修改原数组,只会返回一个包含了原数组中提取的部分元素的一个新数组。

var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8];
var tempArr = arr.splice(0,4); // [0, 1, 2, 3]
console.log(tempArr);
var newArr = [];
console.log(newArr); // []
newArr.push(tempArr);
console.log(newArr); // [[0, 1, 2, 3]]
console.log(arr); // [4, 5, 6, 7, 8]
tempArr = arr.splice(0, 4);
console.log(tempArr); // [4, 5, 6, 7]
newArr.push(tempArr);
console.log(newArr); // [[0, 1, 2, 3], [4, 5, 6, 7]]
console.log(arr); // [8]
tempArr = arr.splice(0, 4);
console.log(tempArr); // [8]
newArr.push(tempArr);
console.log(newArr); // [[0, 1, 2, 3], [4, 5, 6, 7], [8]]
console.log(arr); // []

splice(start, deleteCount)表不从数组start开始删除deleteCount个元素,并且把删除的数组元素组成一个新数组,原数组保留未删除的数组项。splice()方法和slice()方法不同,splice()方法会直接对数组进行修改。

接下来,咱们来看看chunk()函数功能如何实现。

实现方法

方法一

function chunk(arr, size) {
  var tempArr = [],
      newArr=[],
      len = arr.length;
  if (len <= size || size <=0){
    return arr;
  } else {
    for (var i = 0; i < len; i += size) {
      tempArr = arr.slice(i, i + size);
      // arr=[0,1,2,3,4,5,6,7,8] && size = 4 && arr.length = 9
      // 1st => i = 0 => yes => i+=size=4 => arr.slice(0,4)=>[0,1,2,3]
      // 2st => i = 4 => yes => i+=size=8 => arr.slice(4,8)=>[4,5,6,7]
      // 3st => i = 8 => yes => i+=size=12=> arr.slice(8,12)=>[8]
      // 4st => i = 12=> no
      newArr.push(tempArr);
    }
  }
  return newArr;
}

方法二

function chunk (arr, size) {
  var tempArr = [],
      newArr = [];

  for (var i in arr) {
    if (i % size !== size -1){
      tempArr.push(arr[i]);
    } else {
      tempArr.push(arr[i]);
      newArr.push(tempArr);
      tempArr = [];
    }
  }

  if (tempArr.length !== 0){
    newArr.push(tempArr);
    return newArr;
  }
}

方法三

function chunk (arr, size) {
  var tempArr = [],
      newArr = [];

  for (var i in arr) {
    if (i != 0 && i % size === 0) {
      newArr.push(tempArr)
      tempArr = []
    }
    tempArr.push(arr[i])
  }
  if (tempArr.length) {
    newArr.push(tempArr)
  }

  return newArr;
}

方法四

function chunk (arr, size) {
  var newArr = [];

  for (var i = 0; i < arr.length; i++) {
    if (i % size === 0) {
      newArr.unshift([]);
    }
    newArr[0].push(arr[i]);
  }

  newArr.reverse();
  return newArr;
}

方法五

function chunk(arr, size) {
  var newArr = [],
      tempArr = [];
  for(var i=0,len=arr.length;i<len;i++){
    tempArr.push(arr[i]);
    if((i+1)%size === 0 || i === len - 1){
      newArr.push(tempArr);
      tempArr = [];
    }
  }
  return ( newArr );
}

方法六

function chunk(arr, size) {
  var tempArr = [],
      newArr = [],
      len = arr.length,
      i = 0;
  while(i < len) {
    tempArr = arr.splice(0, size);
    newArr.push(tempArr);
    i += size;
    // arr=[0,1,2,3,4,5,6,7,8] && size = 4 && arr.length = 9
    // 1st => i = 0 => yes => arr.splice(0,4)=> tempArr=[0,1,2,3] =>arr=[4,5,6,7,8] (i=4,size=4)
    // 2st => i = 4 => yes => arr.splice(0,4)=> tempArr=[4,5,6,7] =>arr=[8] (i=8,size=4)
    // 3st => i = 8 => yes => arr.splice(0,4)=> tempArr=[8] => arr = [] (i=12,size=4)
    // 4st => i= 12 => no
  }
  return newArr;
}

方法七

function chunk (arr, size) { 

  var tempArr = [],
      newArr = [], 
      i = 0, 
      len = arr.length; 

  while (i < len) { 
    tempArr = arr.slice(i, i += size);
    newArr.push(tempArr);
    // arr=[0,1,2,3,4,5,6,7,8] && size = 4 && arr.length = 9
    // 1st => i = 0 => yes => arr.slice(0, 4) => tempArr = [0,1,2,3] => arr = [0,1,2,3,4,5,6,7,8] (i = 4, size=4)
    // 2st => i = 4 => yes => arr.slice(4, 8) => tempArr = [4,5,6,7] => arr = [0,1,2,3,4,5,6,7,8] (i = 8, size=4)
    // 3st => i = 8 => yes => arr.slice(8,12) => tempArr = [8] => arr = [0,1,2,3,4,5,6,7,8] (i = 12, size = 4)
    // 4st => i = 12 => no
  } 

  return newArr; 
} 

方法八

function chunk(arr, size) {
  var tempArr = [],
      newArr = [],
      i = 0,
      len = arr.length;
  while(i < len){
    if(i + (size - 1) < len){
      tempArr = arr.slice(i, i + size);
    }else{
      tempArr = arr.slice(i, len);
    }
    i += size;
    newArr.push(tempArr);
  }
  return newArr;
}

方法九

function chunk(arr, size) {  
  var iter = Math.floor(arr.length / size);
  var newArr = [];
  var len = arr.length;
  for (var i = 0; i < iter; i++) {
    var tempArr = [];
    for (var x = 0; x < size; x++) {
      tempArr.push(arr[x]);
    }
    arr.splice(0, size);
    newArr.push(tempArr);
  }
  if (arr.length > 0) {
    newArr.push(arr);
  }
  return newArr;
}

总结

文章罗列了多种实现chunk(arr,size)方法。实现将指定数组按给定长度分割,从而实现一个多维数组。虽然方法有多种,但都是slice()splice()push()以及配合for循环实现的。可谓是万变不离其中。希望文中的方法对您有所帮助,如果你有更好的方案或思路,欢迎在下面的评论中一起分享。

大漠

常用昵称“大漠”,W3CPlus创始人,目前就职于手淘。对HTML5、CSS3和Sass等前端脚本语言有非常深入的认识和丰富的实践经验,尤其专注对CSS3的研究,是国内最早研究和使用CSS3技术的一批人。CSS3、Sass和Drupal中国布道者。2014年出版《图解CSS3:核心技术与案例实战》。

如需转载,烦请注明出处:http://www.w3cplus.com/javascript/chunky-monkey-javascript.html

返回顶部