วิธีแบ่งอาร์เรย์แบบยาวออกเป็นอาร์เรย์ขนาดเล็กด้วย JavaScript


100

ฉันมีอีเมลหลายชุด (อาจเป็นอีเมลเพียง 1 ฉบับหรือ 100 อีเมล) และฉันต้องการส่งอาร์เรย์พร้อมคำขอ ajax (ซึ่งฉันรู้วิธีทำ) แต่ฉันสามารถส่งได้เฉพาะอาร์เรย์ที่มี อีเมล 10 ฉบับหรือน้อยกว่าในนั้น ดังนั้นหากมีอาร์เรย์เดิม 20 อีเมลฉันจะต้องแบ่งออกเป็น 2 อาร์เรย์ละ 10 หรือถ้ามีอีเมล 15 ฉบับในอาร์เรย์เดิมจากนั้นอาร์เรย์ 1 รายการจาก 10 และอีกอาร์เรย์ 5 ฉันใช้ jQuery วิธีที่ดีที่สุดในการทำเช่นนี้คืออะไร?

คำตอบ:


195

อย่าใช้ jquery ... ใช้ javascript ธรรมดา

var a = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];

var b = a.splice(0,10);

//a is now [11,12,13,14,15];
//b is now [1,2,3,4,5,6,7,8,9,10];

คุณสามารถวนซ้ำเพื่อให้ได้พฤติกรรมที่คุณต้องการ

var a = YOUR_ARRAY;
while(a.length) {
    console.log(a.splice(0,10));
}

สิ่งนี้จะให้คุณได้ 10 องค์ประกอบต่อครั้ง ... ถ้าคุณพูด 15 องค์ประกอบคุณจะได้ 1-10, 11-15 ตามที่คุณต้องการ


9
โปรดทราบว่า YOUR_ARRAY จะถูกใช้ไปด้วยเช่นกัน (อาร์เรย์คือวัตถุ ... )
Claudio

ใช่ฉันแค่ใส่สิ่งนั้นเพราะ a ไม่สามารถอธิบายได้และฉันก็เขียนตัวอย่างโดยใช้ ... มันเป็นบรรทัดรหัสที่ไม่จำเป็นอย่างสมบูรณ์ ... แม้ว่านั่นจะทำให้ฉันคิดว่า ... ถ้าใช้รูปแบบนี้ คุณอาจต้องการทำสำเนาลึกลงในอาร์เรย์ที่ใช้งานได้เพื่อไม่ให้รบกวนต้นฉบับของคุณ
jyore

@junvar IDK ถ้า 1 ซับใช้งานได้ในปี 2018 (ฉันสงสัยอย่างจริงจัง) แต่มันล้มเหลวในวันนี้ คุณไม่ควรกลายพันธุ์ (เช่นลบองค์ประกอบ) อาร์เรย์ที่ถูกทำซ้ำมันจะพ่นออกจากดัชนีกล่าวคือหลังจากการลบแต่ละครั้งควรปรับเปลี่ยนใหม่ตามจำนวนองค์ประกอบที่ลบออกดังนั้นจึง "ข้ามไปข้างหน้า" และไม่กิน อาร์เรย์ทั้งหมด ลองเลย
Drew Reese

107
var size = 10; var arrayOfArrays = [];
for (var i=0; i<bigarray.length; i+=size) {
     arrayOfArrays.push(bigarray.slice(i,i+size));
}
console.log(arrayOfArrays);

ซึ่งแตกต่างจากsplice(), slice()คือไม่ทำลายไปยังอาร์เรย์เดิม


1
วิธีนี้ดีกว่า
Maduekwe Pedro

38

เพียงแค่วนซ้ำอาร์เรย์แล้วเชื่อมต่อจนกว่าจะใช้หมด



var a = ['a','b','c','d','e','f','g']
  , chunk

while (a.length > 0) {

  chunk = a.splice(0,3)

  console.log(chunk)

}

เอาท์พุท


[ 'a', 'b', 'c' ]
[ 'd', 'e', 'f' ]
[ 'g' ]



13

สมมติว่าคุณไม่ต้องการทำลายอาร์เรย์เดิมคุณสามารถใช้โค้ดเช่นนี้เพื่อแยกอาร์เรย์แบบยาวออกเป็นอาร์เรย์ขนาดเล็กซึ่งคุณสามารถทำซ้ำได้:

var longArray = [];   // assume this has 100 or more email addresses in it
var shortArrays = [], i, len;

for (i = 0, len = longArray.length; i < len; i += 10) {
    shortArrays.push(longArray.slice(i, i + 10));
}

// now you can iterate over shortArrays which is an 
// array of arrays where each array has 10 or fewer 
// of the original email addresses in it

for (i = 0, len = shortArrays.length; i < len; i++) {
    // shortArrays[i] is an array of email addresss of 10 or less
}

6

การใช้งานอื่น:

const arr = ["H", "o", "w", " ", "t", "o", " ", "s", "p", "l", "i", "t", " ", "a", " ", "l", "o", "n", "g", " ", "a", "r", "r", "a", "y", " ", "i", "n", "t", "o", " ", "s", "m", "a", "l", "l", "e", "r", " ", "a", "r", "r", "a", "y", "s", ",", " ", "w", "i", "t", "h", " ", "J", "a", "v", "a", "S", "c", "r", "i", "p", "t"];

const size = 3; 
const res = arr.reduce((acc, curr, i) => {
  if ( !(i % size)  ) {    // if index is 0 or can be divided by the `size`...
    acc.push(arr.slice(i, i + size));   // ..push a chunk of the original array to the accumulator
  }
  return acc;
}, []);

// => [["H", "o", "w"], [" ", "t", "o"], [" ", "s", "p"], ["l", "i", "t"], [" ", "a", " "], ["l", "o", "n"], ["g", " ", "a"], ["r", "r", "a"], ["y", " ", "i"], ["n", "t", "o"], [" ", "s", "m"], ["a", "l", "l"], ["e", "r", " "], ["a", "r", "r"], ["a", "y", "s"], [",", " ", "w"], ["i", "t", "h"], [" ", "J", "a"], ["v", "a", "S"], ["c", "r", "i"], ["p", "t"]]

NB - ไม่ได้แก้ไขอาร์เรย์เดิม

หรือหากคุณต้องการใช้งานได้ 100% ไม่เปลี่ยนรูป (แม้ว่าจะไม่มีอะไรเลวร้ายในการกลายพันธุ์เหมือนที่ทำข้างต้น) และวิธีการที่มีอยู่ในตัว:

function splitBy(size, list) {
  return list.reduce((acc, curr, i, self) => {
    if ( !(i % size)  ) {  
      return [
          ...acc,
          self.slice(i, i + size),
        ];
    }
    return acc;
  }, []);
}

5

เป็นส่วนเสริมของคำตอบของ @jyore และในกรณีที่คุณยังคงต้องการเก็บอาร์เรย์เดิม:

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

var splitArray = function (arr, size) {

  var arr2 = arr.slice(0),
      arrays = [];

  while (arr2.length > 0) {
      arrays.push(arr2.splice(0, size));
  }

  return arrays;
}

splitArray(originalArray, 2);
// originalArray is still = [1,2,3,4,5,6,7,8];

5

Array.reduce อาจไม่มีประสิทธิภาพสำหรับอาร์เรย์ขนาดใหญ่โดยเฉพาะอย่างยิ่งกับตัวดำเนินการ mod ฉันคิดว่าโซลูชันการทำงานที่สะอาดกว่า (และอาจอ่านง่ายกว่า) จะเป็นดังนี้:

const chunkArray = (arr, size) =>
  arr.length > size
    ? [arr.slice(0, size), ...chunkArray(arr.slice(size), size)]
    : [arr];

3

อีกวิธีหนึ่ง:

var longArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var size = 2;

var newArray = new Array(Math.ceil(longArray.length / size)).fill("")
    .map(function() { return this.splice(0, size) }, longArray.slice());

// newArray = [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]];

สิ่งนี้ไม่มีผลต่ออาร์เรย์ดั้งเดิมในรูปแบบสำเนาที่สร้างโดยใช้ชิ้นส่วนจะถูกส่งไปยังอาร์กิวเมนต์ "this" ของแผนที่


3

ฉันอยากจะแบ่งปันวิธีแก้ปัญหาของฉันด้วย มันละเอียดกว่าเล็กน้อย แต่ใช้งานได้ดี

var data = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];

var chunksize = 4;


var chunks = [];

data.forEach((item)=>{
  if(!chunks.length || chunks[chunks.length-1].length == chunksize)
  chunks.push([]);

  chunks[chunks.length-1].push(item);
});

console.log(chunks);

เอาต์พุต (จัดรูปแบบ):

[ [ 1,  2,  3,  4],
  [ 5,  6,  7,  8],
  [ 9, 10, 11, 12],
  [13, 14, 15    ] ]

2

การใช้งานอื่นโดยใช้ Array.reduce (ฉันคิดว่ามันเป็นสิ่งเดียวที่หายไป!):

const splitArray = (arr, size) =>
{
    if (size === 0) {
        return [];
    }

    return arr.reduce((split, element, index) => {
        index % size === 0 ? split.push([element]) : split[Math.floor(index / size)].push(element);
        return split;
    }, []);
};

วิธีแก้ปัญหามากมายข้างต้นคนนี้ไม่ทำลายล้าง ส่งคืนอาร์เรย์ว่างเมื่อขนาดเป็น 0 เป็นเพียงแบบแผน หากifละเว้นบล็อกคุณจะได้รับข้อผิดพลาดซึ่งอาจเป็นสิ่งที่คุณต้องการ


1

คุณสามารถดูรหัสนี้ ง่ายและมีประสิทธิภาพ

function chunkArrayInGroups(array, unit) {
var results = [],
length = Math.ceil(array.length / unit);

for (var i = 0; i < length; i++) {
    results.push(array.slice(i * unit, (i + 1) * unit));
}
 return results;
}

chunkArrayInGroups(["a", "b", "c", "d"], 2);

1

นี่คือซับง่ายๆ

var segment = (arr, n) => arr.reduce((r,e,i) => i%n ? (r[r.length-1].push(e), r)
                                                    : (r.push([e]), r), []),
        arr = Array.from({length: 31}).map((_,i) => i+1);
console.log(segment(arr,7));


1

กะทัดรัดมากขึ้น:

const chunk = (xs, size) =>
  xs.map((_, i) =>
    (i % size === 0 ? xs.slice(i, i + size) : null)).filter(Boolean);
    
// Usage:
const sampleArray = new Array(33).fill(undefined).map((_, i) => i);

console.log(chunk(sampleArray, 5));


0

หากคุณต้องการวิธีที่ไม่แก้ไขอาร์เรย์ที่มีอยู่ให้ลองทำดังนี้:

let oldArray = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];
let newArray = [];
let size = 3; // Size of chunks you are after
let j = 0; // This helps us keep track of the child arrays

for (var i = 0; i < oldArray.length; i++) {
  if (i % size === 0) {
    j++
  }
  if(!newArray[j]) newArray[j] = [];
  newArray[j].push(oldArray[i])
}

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

    for (var i=0; arr.length>size; i++){
    newArr.push(arr.splice(0,size));
    }
    newArr.push(arr.slice(0));
    return newArr;

}

chunkArrayInGroups([0, 1, 2, 3, 4, 5, 6], 3);

อย่าลืมทำ: newArr = [] ตัวแปรท้องถิ่น
zgthompson

คำตอบที่ใช้รหัสเท่านั้นมักจะถูกตั้งค่าสถานะและลบออกเนื่องจากเป็นคุณภาพต่ำ คุณช่วยให้ความเห็นเกี่ยวกับวิธีแก้ปัญหาเดิมได้อย่างไร
Graham

จะใช้ไม่ได้ถ้าขนาดก้อนน้อยกว่าขนาดอาร์เรย์อินพุต
r3wt

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

    for (var i=0; i < arr.length; i+= size){
    newArr.push(arr.slice(i,i+size));
    }
    return newArr;

}

chunkArrayInGroups([0, 1, 2, 3, 4, 5, 6], 3);

2
ยินดีต้อนรับสู่ stackoverflow คำตอบของคุณจะได้รับการปรับปรุงโดยการเพิ่มคำอธิบาย
Simon.SA

0

เป็นฟังก์ชัน

var arrayChunk = function (array, chunkSize) {
            var arrayOfArrays = [];

            if (array.length <= chunkSize) {
                arrayOfArrays.push(array);
            } else {
                for (var i=0; i<array.length; i+=chunkSize) {
                    arrayOfArrays.push(array.slice(i,i+chunkSize));
                }
            }
            return arrayOfArrays;
        }

ใช้

arrayChunk(originalArray, 10) //10 being the chunk size.

0

ใช้การเรียกซ้ำ

let myArr = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16];
let size = 4; //Math.sqrt(myArr.length); --> For a n x n matrix
let tempArr = [];
function createMatrix(arr, i) {
    if (arr.length !== 0) {
      if(i % size == 0) {
        tempArr.push(arr.splice(0,size))
      } 
      createMatrix(arr, i - 1)
    }
}
createMatrix(myArr, myArr.length);
console.log(tempArr);

หมายเหตุ: อาร์เรย์ที่มีอยู่เช่น myArr จะถูกแก้ไข


0

โดยใช้ต้นแบบเราสามารถตั้งค่าโดยตรงกับคลาสอาร์เรย์

Array.prototype.chunk = function(n) {
  if (!this.length) {
    return [];
  }
  return [this.slice(0, n)].concat(this.slice(n).chunk(n));
};
console.log([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15].chunk(5));


0
const originalArr = [1,2,3,4,5,6,7,8,9,10,11];
const splittedArray = [];
  while (originalArr.length > 0) {
    splittedArray.push(originalArr.splice(0,range));  
  }

เอาต์พุตสำหรับช่วง 3

splittedArray === [[1,2,3][4,5,6][7,8,9][10,11]]

เอาต์พุตสำหรับช่วง 4

splittedArray === [[1,2,3,4][5,6,7,8][9,10,11]]

คุณช่วยเพิ่มคำอธิบายได้ไหม
อาตมา
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.