খণ্ডগুলিতে অ্যারে বিভক্ত করুন


515

ধরা যাক যে আমার কাছে জাভাস্ক্রিপ্ট অ্যারেটি নীচের মতো দেখাচ্ছে:

["Element 1","Element 2","Element 3",...]; // with close to a hundred elements.

অ্যারেটিকে ছোট ছোট অ্যারেগুলিতে বিভক্ত করা (বিভাজন) করার জন্য কোন পদ্ধতির উপযুক্ত হবে, এটি বলা যাক, এটির 10 টির বেশি উপাদান?




24
জন্য lodash ব্যবহারকারীকে আপনার খুঁজছেন _.chunk
ইউলিস বিএন 14

2
আমি কেবল চেষ্টা করেছি const chunk = (arr, n) => arr.length ? [arr.slice(0, n), ...chunk(arr.slice(n), n)] : []যা সুন্দর এবং সংক্ষিপ্ত তবে প্রায় 1000 টি উপাদানগুলির জন্য @ আইমকিডন এর উত্তর হিসাবে 106 এবং যতদিন 10,000 টি উপাদান হিসাবে 1,058 ডলার হিসাবে প্রায় 256% লাগবে!
তোফ

আপনার যদি সর্বশেষ অংশের ন্যূনতম আকারের প্রয়োজন হয় তবে এখানে বিকল্পগুলি রয়েছে: স্ট্যাকওভারফ্লো
আহমেট সিটিন

উত্তর:


640

Array.slice পদ্ধতি, শুরু, মধ্যম, বা যাই হোক না কেন উদ্দেশ্যে প্রয়োজন জন্য একটি অ্যারের শেষ থেকে একটি ফালি নিষ্কাশন করতে পারেন মূল অ্যারের পরিবর্তন না করে।

var i,j,temparray,chunk = 10;
for (i=0,j=array.length; i<j; i+=chunk) {
    temparray = array.slice(i,i+chunk);
    // do whatever
}

19
মনে রাখবেন এটি chunkসত্তার বিরুদ্ধে জোর দেওয়ার জন্য কোনও ব্যবহারের ফাংশন কিনা 0। (অসীম লুপ)
স্টিভেন লু

19
নাহ, শেষ অংশটি অন্যদের চেয়ে ছোট হওয়া উচিত।
ব্লেজমোনজার

7
@ ব্লাজমোনজার, সত্যিই! পরবর্তী সময় সিদ্ধান্তে ঝাঁপ দেওয়ার আগে আমি নিজে চেষ্টা করে দেখব। আমি ধরে নিয়েছি (ভুলভাবে) অ্যারেতে একটি ইনপুট পাস করা। স্লাইস যা অ্যারের সীমা অতিক্রম করেছে, তবে এটি ঠিক নিখুঁতভাবে কাজ করে!
rysqui

55
এক-liners, (চেইন-প্রেমীদের) এর জন্য : const array_chunks = (array, chunk_size) => Array(Math.ceil(array.length / chunk_size)).fill().map((_, index) => index * chunk_size).map(begin => array.slice(begin, begin + chunk_size));
Ван

8
তোমার জে দরকার কেন? প্রথমে আমি ভাবলাম এটি একটি অপটিমাইজেশন, তবে এটি আসলে (i = 0; i <অ্যারে দৈর্ঘ্য; i ++) এর চেয়ে ধীর is
অ্যালেক্স

149

Dbaseman দ্বারা একটি উত্তর থেকে পরিবর্তিত: https://stackoverflow.com/a/10456344/711085

Object.defineProperty(Array.prototype, 'chunk_inefficient', {
  value: function(chunkSize) {
    var array = this;
    return [].concat.apply([],
      array.map(function(elem, i) {
        return i % chunkSize ? [] : [array.slice(i, i + chunkSize)];
      })
    );
  }
});

console.log(
  [1, 2, 3, 4, 5, 6, 7].chunk_inefficient(3)
)
// [[1, 2, 3], [4, 5, 6], [7]]


গৌণ সংযোজন :

আমার উল্লেখ করা উচিত যে উপরেরটি ব্যবহার করার মতো একটি-নয়-মার্জিত (মনে মনে) কাজ Array.map। এটি মূলত নিম্নলিখিতটি করে যেখানে ~ সংমিশ্রণ:

[[1,2,3]]~[]~[]~[] ~ [[4,5,6]]~[]~[]~[] ~ [[7]]

এটিতে নীচের পদ্ধতির মতো একই অ্যাসিম্পটোটিক চলমান সময় রয়েছে তবে খালি তালিকা তৈরির কারণে সম্ভবত আরও খারাপ ধ্রুবক ফ্যাক্টর। এটি নিম্নরূপ কেউ এটিকে আবার লিখতে পারে (বেশিরভাগই ব্লেজমোনজারের পদ্ধতির মতো, যার কারণে আমি এই উত্তরটি মূলত জমা করিনি):

আরও কার্যকর পদ্ধতি:

// refresh page if experimenting and you already defined Array.prototype.chunk

Object.defineProperty(Array.prototype, 'chunk', {
  value: function(chunkSize) {
    var R = [];
    for (var i = 0; i < this.length; i += chunkSize)
      R.push(this.slice(i, i + chunkSize));
    return R;
  }
});

console.log(
  [1, 2, 3, 4, 5, 6, 7].chunk(3)
)


আজকাল আমার পছন্দের উপায়টি উপরের বা নীচের একটি:

Array.range = function(n) {
  // Array.range(5) --> [0,1,2,3,4]
  return Array.apply(null,Array(n)).map((x,i) => i)
};

Object.defineProperty(Array.prototype, 'chunk', {
  value: function(n) {

    // ACTUAL CODE FOR CHUNKING ARRAY:
    return Array.range(Math.ceil(this.length/n)).map((x,i) => this.slice(i*n,i*n+n));

  }
});

ডেমো:

> JSON.stringify( Array.range(10).chunk(3) );
[[1,2,3],[4,5,6],[7,8,9],[10]]

অথবা আপনি যদি অ্যারে.আরঞ্জ ফাংশনটি না চান তবে এটি আসলে একটি ওয়ান-লাইনার (ফ্লাফ বাদে):

var ceil = Math.ceil;

Object.defineProperty(Array.prototype, 'chunk', {value: function(n) {
    return Array(ceil(this.length/n)).fill().map((_,i) => this.slice(i*n,i*n+n));
}});

অথবা

Object.defineProperty(Array.prototype, 'chunk', {value: function(n) {
    return Array.from(Array(ceil(this.length/n)), (_,i)=>this.slice(i*n,i*n+n));
}});

41
হ্যাঁ, chunkঅ্যারেতে ফাংশনটি কল করা থেকে আপনি যে শীতলতা বোধ করছেন তা আমি প্রোটোটাইপের সাথে গোলযোগ এড়াতে চাইছি না কারণ আপনি যে অতিরিক্ত জটিলতা যুক্ত করছেন এবং যে সূক্ষ্ম বাগগুলি অন্তর্নির্মিত প্রোটোটাইপগুলির সাথে বিশৃঙ্খলা সৃষ্টি করতে পারে তার চেয়ে বেশি নয়।
গর্ডন গুস্তাফসন

12
তিনি তাদের সাথে ঝামেলা করছেন না তিনি অ্যারেগুলির জন্য তাদের প্রসারিত করছেন। আমি কখনই অবজেক্ট.প্রোটোটাইপ স্পর্শ করতে বুঝতে পারি না কারণ এটি সমস্ত বস্তুগুলিকে (সবকিছু) বুদবুদ করবে কিন্তু এই অ্যারে নির্দিষ্ট ফাংশনের জন্য আমি কোনও সমস্যা দেখছি না।
রলেমন

চমত্কার নিশ্চিত হতে হবে যে array.map(function(i)না array.map(function(elem,i)যদিও
নিগেল দেবদূত

3
মোজিলা দেব সাইটটিতে সামঞ্জস্যতা চার্টের ভিত্তিতে, আই 9 + এর জন্য অ্যারে.ম্যাপ। সাবধান হও.
মাইকেল ডি

ভাসমানটি পাস করতে সাবধান হন - 7.5 ধরণের সংখ্যার - অবিশ্বাস্য অংশগুলিতে নেতৃত্ব দিন
গাল ব্রাচা

102

অ্যারে.প্রোটোটাইপ সহ নেটিভ প্রোটোটাইপগুলির সাথে কৃপণতা এড়াতে চেষ্টা করুন যদি আপনি না জানেন তবে কে আপনার কোডটি গ্রাস করবে (তৃতীয় পক্ষ, সহকর্মী, পরে কোনও তারিখে নিজেকে)।

প্রোটোটাইপগুলি নিরাপদে প্রসারিত করার উপায় রয়েছে (তবে সমস্ত ব্রাউজারে নয়) এবং বর্ধিত প্রোটোটাইপগুলি থেকে তৈরি বস্তুগুলি নিরাপদে গ্রাস করার উপায় রয়েছে তবে কমপক্ষে আশ্চর্যের নীতি অনুসরণ করা এবং এই অভ্যাসগুলি পুরোপুরি এড়িয়ে যাওয়া আঙ্গুলের আরও ভাল নিয়ম ।

আপনার যদি কিছুটা সময় থাকে তবে এ বিষয় সম্পর্কে ভাল আলোচনার জন্য অ্যান্ড্রু ডুপন্টের জেএসকনফ ২০১১-এর আলোচনা, "সবকিছুই অনুমোদিত: বিল্ট-ইনগুলি প্রসারিত করা" দেখুন

তবে প্রশ্নটিতে ফিরে আসা, যখন উপরের সমাধানগুলি কাজ করবে, তারা অত্যধিক জটিল এবং অপ্রয়োজনীয় কম্পিউটেশনাল ওভারহেডের প্রয়োজন। এখানে আমার সমাধান:

function chunk (arr, len) {

  var chunks = [],
      i = 0,
      n = arr.length;

  while (i < n) {
    chunks.push(arr.slice(i, i += len));
  }

  return chunks;
}

// Optionally, you can do the following to avoid cluttering the global namespace:
Array.chunk = chunk;

25
"নেটিভ প্রোটোটাইপগুলির সাথে কৌতুক এড়ান" নতুন জেএস বিকাশকারীদের এই শব্দগুচ্ছটির স্থায়ী না হলে একটি অস্থায়ী হওয়া উচিত।
জ্যাকব ডালটন

2
আমি কয়েক বছর ধরে জাভাস্ক্রিপ্ট ব্যবহার করে আসছি এবং প্রোটোটাইপ নিয়ে বিরক্ত না করে পরের দিকে অতি ব্যস্ত হয়ে উঠি, কখনও কখনও আপনি কিছু লোকের মত পরিবর্তন করেন না।
1984

2
আমার চোখে সেরা পরামর্শ, বোঝার সহজতম এবং বাস্তবায়নের জন্য আপনাকে অনেক ধন্যবাদ!
ওলগা ফারবার

1
@ জ্যাকবডাল্টন আমার মনে হয় এটি সমস্ত বিশ্ববিদ্যালয়ের দোষ। লোকেরা মনে করে যে ওওপি অবশ্যই সর্বত্র ব্যবহার করা উচিত। সুতরাং তারা "কেবল একটি ফাংশন তৈরি করতে" ভয় পাচ্ছে। তারা এটি কোনও কিছুর ভিতরে রাখার বিষয়ে নিশ্চিত হতে চান। এমনকি এটি মোটেই উপযুক্ত না হলেও। যদি কোনও ডট স্বীকৃতি না থাকে তবে কোনও "আর্কিটেকচার" নেই।
গেরম্যান

102

হ্রাস ব্যবহার করে এখানে একটি ES6 সংস্করণ

var perChunk = 2 // items per chunk    

var inputArray = ['a','b','c','d','e']

var result = inputArray.reduce((resultArray, item, index) => { 
  const chunkIndex = Math.floor(index/perChunk)

  if(!resultArray[chunkIndex]) {
    resultArray[chunkIndex] = [] // start a new chunk
  }

  resultArray[chunkIndex].push(item)

  return resultArray
}, [])

console.log(result); // result: [['a','b'], ['c','d'], ['e']]

এবং আপনি আরও মানচিত্রের শৃঙ্খলা তৈরি করতে / রূপান্তরগুলি হ্রাস করতে প্রস্তুত। আপনার ইনপুট অ্যারে অক্ষত আছে


যদি আপনি একটি সংক্ষিপ্ত তবে কম পঠনযোগ্য সংস্করণ পছন্দ করেন তবে concatএকই ফলাফলের জন্য আপনি কিছুটা মিশ্রণে ছিটিয়ে দিতে পারেন :

inputArray.reduce((all,one,i) => {
   const ch = Math.floor(i/perChunk); 
   all[ch] = [].concat((all[ch]||[]),one); 
   return all
}, [])

এটি সবচেয়ে ঘন সমাধান হিসাবে মনে হচ্ছে। চুঙ্কইন্ডেক্স = ম্যাথ.ফ্লুর (সূচক / পারকঙ্ক) কী পাচ্ছে? এটা কি গড়?
me-me

5/2 = 2.5এবং Math.floor(2.5) = 2তাই সূচী 5 সহ আইটেম বালতি 2
Andrei আর

ধন্যবাদ আন্দ্রে আর। আহ তাই এটি 0 - 2 এর মধ্য দিয়ে যায় So সুতরাং গণিতের পদগুলিতে এটিকে কী বলা হয়? আমার অনুমান আমার বক্তব্য হ'ল প্রতিটি স্লাইসের সূচক পেতে আমি প্রতিটি সূচককে 2/2 ভাগ করার চিন্তা করিনি। তাই আমি এটির চারপাশে আমার মাথাটি গুটিয়ে দেওয়ার চেষ্টা করছি কারণ আমি সত্যিই এটি পছন্দ করি তবে এটি ম্যাথের পদগুলিতে পুরোপুরি বুঝতে পারি না। আমি মোট সংখ্যার গড় পেতে সাধারণত এটি করি তবে এটি অন্যরকম দেখাচ্ছে।
me-me

অন্যান্য সমাধানের সাথে তুলনা করার সময় এই সমাধানটি অকার্যকর কারণ আপনাকে প্রতিটি উপাদান দিয়ে পুনরাবৃত্তি করতে হবে।
জেপি ডি লা

আপনি ঠিক বলেছেন @ জেপডেলাটোরে, এটি স্লাইস অ্যারেগুলির মতো সমাধানগুলির মতো সম্ভবত দক্ষ নয়, তবে আপনি এখানে চুল ভাগ করছেন। তালিকাভুক্ত বেশিরভাগ উত্তরগুলি সেই সংজ্ঞা দ্বারা অকার্যকর হবে।
Andrei আর

51

আমি jsperf.com এ বিভিন্ন উত্তর পরীক্ষা করেছি। ফলাফলটি এখানে পাওয়া যায়: https://web.archive.org/web/20150909134228/https://jsperf.com/chunk-mtds

এবং দ্রুততম ফাংশন (এবং এটি আই 8 থেকে কাজ করে) এটি একটি:

function chunk(arr, chunkSize) {
  var R = [];
  for (var i=0,len=arr.length; i<len; i+=chunkSize)
    R.push(arr.slice(i,i+chunkSize));
  return R;
}

1
এই বেঞ্চমার্কটি তৈরি করার জন্য @ অ্যাম কেডনকে ধন্যবাদ: এটি এত সহায়ক ছিল! আমি স্প্লাইস পদ্ধতির ব্যবহার করছি এবং এটি আমার ক্রোম ভি 70 ব্রাউজারটি 884432 আকারের আকারে ক্র্যাশ করেছে your :)
বেনি নিউজবাউয়ার

34

আমি স্প্লাইস পদ্ধতি ব্যবহার করতে পছন্দ করব :

var chunks = function(array, size) {
  var results = [];
  while (array.length) {
    results.push(array.splice(0, size));
  }
  return results;
};

16
এই স্প্লাইস দ্রবণটির সাথে অবশ্যই সতর্কতা অবলম্বন করা উচিত কারণ এটি আসল অ্যারেটি সংশোধন করে, তাই পার্শ্ব প্রতিক্রিয়াগুলি স্পষ্ট করে ডকুমেন্ট করতে ভুলবেন না।
বিডিআরএক্স

3
তারপরে স্লাইসটি ব্যবহার করুন
এমপ্লুঞ্জন

@ এমপ্লুংজান ফালি ব্যবহার করার সময় বার বার একই অ্যারে হবে be সুতরাং এটি আরও কিছু পরিবর্তন ছাড়া সত্যই কোনও ড্রপ-ইন প্রতিস্থাপন নয়।
nietonfir

আমি এই উত্তরে কেবল যুক্ত করব তা হ'ল আসল অ্যারের ক্লোন । আমি ES6 এর স্প্রেড অপারেটর দিয়ে এটি করব। var clone = [...array]তারপরে সেই ক্লোন করা অ্যারেতে দৈর্ঘ্য পরীক্ষা করা এবং স্প্লিক্লিং করুন।
মরিসিওলিওল

1
অথবা আপনি যদি ES6 বৈশিষ্ট্যগুলি ব্যবহার না করতে পারেন তবে আপনি কেবল এটি করতে পারেন array = array.slice()যা অগভীর অনুলিপি তৈরি করে।
3limin4t0r

34

ইসিএমএ 6-এ ওয়ান-লাইনার

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

new Array(Math.ceil(list.length / chuckSize)).fill().map(_ => list.splice(0,chuckSize))

9
এটি আসল listঅ্যারেটি পরিবর্তন করে
জ্যাকা

6
.স্লাইস () ব্যবহার করে সহজ ফিক্স ...map((_,i) => list.slice(i*chuckSize,i*chuckSize+chuckSize))
জেমস রবি

2
জেএসপিআইপি-এ এটি অন্যান্য উত্তরগুলির তুলনায় মারাত্মকভাবে আরও পারফরম্যান্স।
মিকা হেনিং

30

পুরানো প্রশ্ন: নতুন উত্তর! আমি আসলে এই প্রশ্নটির উত্তর নিয়ে কাজ করছি এবং এর সাথে আমার এক বন্ধু উন্নত হয়েছিল! সুতরাং এটি এখানে:

Array.prototype.chunk = function ( n ) {
    if ( !this.length ) {
        return [];
    }
    return [ this.slice( 0, n ) ].concat( this.slice(n).chunk(n) );
};

[1,2,3,4,5,6,7,8,9,0].chunk(3);
> [[1,2,3],[4,5,6],[7,8,9],[0]]

14
তবে, এই পদ্ধতির পারফরম্যান্স হ'ল (এন ^ 2), সুতরাং এটি কোডের পারফরম্যান্স-সমালোচনামূলক বিভাগগুলিতে বা দীর্ঘ অ্যারে ব্যবহার করা উচিত নয় (বিশেষত, যখন অ্যারেরটি .lengthখণ্ড-আকারের চেয়ে অনেক বেশি থাকে n)। যদি এটি একটি অলস ভাষা ছিল (জাভাস্ক্রিপ্টের বিপরীতে) তবে এই অ্যালগরিদমটি ও (এন ^ 2) সময় ভোগ করবে না। বলেছিল, পুনরাবৃত্তি বাস্তবায়ন মার্জিত। আপনি সম্ভবত প্রথমে পুনরায় পুনরুক্ত হওয়া কোনও সহায়ক ফাংশনটি সংজ্ঞায়িত করে array,positionতারপরে প্রেরণ করে কর্মক্ষমতা উন্নত করতে এটি পরিবর্তন করতে পারেন : Array.prototype.chunkফিরে
আসুন

আপনার আত্মা দিয়ে আমাকে আশীর্বাদ করার জন্য সানসাইকে ধন্যবাদ যে আমি নিশ্চয়ই আজ রাতের বেলা পাল্টে ফেলেছি
কামড়েছি

1
বা ...var chunk = (arr, n) => { if ( !arr.length ) return []; return [ arr.slice( 0, n ) ].concat( chunk(arr.slice(n), n) ) }
এড উইলিয়ামস

28

আজকাল আপনি অ্যারেটিকে ছোট অ্যারেগুলিতে বিভক্ত করতে লোডাশের অংশ ফাংশনটি ব্যবহার করতে পারেন https://lodash.com/docs#chunk আর লুপগুলি নিয়ে ভাঁড়ার দরকার নেই!


3
আমার কাছে মনে হচ্ছে এসও জাভাস্ক্রিপ্ট প্রশ্নগুলির দাবি অস্বীকার করা উচিত: আপনি কি লোডাশ চেষ্টা করেছেন? আমি নোড বা ব্রাউজারে অন্তর্ভুক্ত খুব প্রথম জিনিস।
জ্যাকব ডালটন

20

অনেক উত্তর আছে তবে আমি এটি ব্যবহার করি:

const chunk = (arr, size) =>
  arr
    .reduce((acc, _, i) =>
      (i % size)
        ? acc
        : [...acc, arr.slice(i, i + size)]
    , [])

// USAGE
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
chunk(numbers, 3)

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

প্রথমে খণ্ড আকার অনুসারে সূচকটি বিভাজন করার সময় বাকী অংশের জন্য অনুসন্ধান করুন।

যদি বাকী কিছু থাকে তবে কেবল সঞ্চয়ের অ্যারেটি ফিরিয়ে দিন।

যদি কোনও অবশিষ্ট না থাকে তবে সূচকটি খণ্ড আকারের দ্বারা বিভাজ্য, সুতরাং মূল অ্যারে থেকে একটি স্লাইস নিন (বর্তমান সূচী থেকে শুরু করে) এবং এটি সংযোজক অ্যারেতে যুক্ত করুন।

সুতরাং, হ্রাসের প্রতিটি পুনরাবৃত্তির জন্য ফেরত সংগ্রহকারী অ্যারে দেখতে কিছুটা এমন দেখাচ্ছে:

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

সুন্দর সমাধান এবং পুনরাবৃত্তির দুর্দান্ত দৃশ্য উপস্থাপনা represent আমি একটি অনুরূপ সমাধান দিয়ে শেষ করেছি যা আমি উত্তর হিসাবে পোস্ট করেছি: stackoverflow.com/a/60779547
এমটিএস

15

জেনারেটর ব্যবহার করে

function* chunks(arr, n) {
 for(let i = 0; i < arr.length; i += n) {
     yield(arr.slice(i, i+n));
     }
}
let someArray = [0,1,2,3,4,5,6,7,8,9]
console.log([...chunks(someArray, 2)]) // [[0,1],[2,3],[4,5],[6,7],[8,9]]


3
আমি প্রায় জেনারেটর ব্যবহার করছিলাম বা আরও জটিলতর সেগুলি ব্যবহার করছিলাম এমন প্রশ্নের উত্তরগুলিতে আমি অবাক হয়েছি। এই সমাধানের সাথে দুর্দান্ত ব্রেভিটি এবং পারফরম্যান্স।
কিথ

14

ঠিক আছে, আসুন মোটামুটি আঁটসাঁট একটি দিয়ে শুরু করুন:

function chunk(arr, n) {
    return arr.slice(0,(arr.length+n-1)/n|0).
           map(function(c,i) { return arr.slice(n*i,n*i+n); });
}

যা এর মতো ব্যবহৃত হয়:

chunk([1,2,3,4,5,6,7], 2);

তারপরে আমাদের এই টাইট হ্রাসকারী ফাংশনটি রয়েছে:

function chunker(p, c, i) {
    (p[i/this|0] = p[i/this|0] || []).push(c);
    return p;
}

যা এর মতো ব্যবহৃত হয়:

[1,2,3,4,5,6,7].reduce(chunker.bind(3),[]);

যেহেতু কোনও thisসংখ্যার সাথে আবদ্ধ হওয়ার পরে একটি বিড়ালছানা মারা যায় , আমরা এর পরিবর্তে ম্যানুয়াল কার্চিং এটি করতে পারি:

// Fluent alternative API without prototype hacks.
function chunker(n) {
   return function(p, c, i) {
       (p[i/n|0] = p[i/n|0] || []).push(c);
       return p;
   };
}

যা এর মতো ব্যবহৃত হয়:

[1,2,3,4,5,6,7].reduce(chunker(3),[]);

তারপরে এখনও পুরো টাইট ফাংশন যা এটি একসাথে করে:

function chunk(arr, n) {
    return arr.reduce(function(p, cur, i) {
        (p[i/n|0] = p[i/n|0] || []).push(cur);
        return p;
    },[]);
}

chunk([1,2,3,4,5,6,7], 3);

আইই 8 তে কাজ করে না।
নাদিম্মন্ন মোহাম্মদ

4
হা! আমি বিড়ালছানা মন্তব্য পছন্দ। দুঃখিত কোন অতিরিক্ত গঠনমূলক ইনপুট :) জন্য
29er

আমি করব (p[i/n|0] || (p[i/n|0] = [])), যাতে আপনি প্রয়োজনীয় না হলে কোনও মান বরাদ্দ করবেন না ...
yckart

12

আমি খাঁটি ES6 এ একটি সাধারণ অ-পরিবর্তনীয় সমাধান তৈরি করার লক্ষ্য নিয়েছিলাম। জাভাস্ক্রিপ্টের অদ্ভুততা ম্যাপিংয়ের আগে খালি অ্যারে পূরণ করা প্রয়োজনীয় করে তোলে :-(

function chunk(a, l) { 
    return new Array(Math.ceil(a.length / l)).fill(0)
        .map((_, n) => a.slice(n*l, n*l + l)); 
}

পুনরাবৃত্তি সহ এই সংস্করণটি সহজ এবং আরও জোরালো বলে মনে হচ্ছে:

function chunk(a, l) { 
    if (a.length == 0) return []; 
    else return [a.slice(0, l)].concat(chunk(a.slice(l), l)); 
}

ES6 এর হাস্যকর দুর্বল অ্যারে ফাংশনগুলি ভাল ধাঁধা তৈরি করে :-)


আমিও অনেকটা এভাবে লিখেছি আমার। আপনি যদি এর 0থেকে অপসারণ করেন তবে এটি এখনও কার্যকর হয় fill, যা fillচেহারাটি আরও কিছুটা বোধগম্য করে তোলে , ইમો।
কোয়ার্ট গ্রোবেলার

12

আমি মনে করি এটি ES6 সিনট্যাক্স সহ একটি দুর্দান্ত পুনরাবৃত্ত সমাধান:

const chunk = function(array, size) {
  if (!array.length) {
    return [];
  }
  const head = array.slice(0, size);
  const tail = array.slice(size);

  return [head, ...chunk(tail, size)];
};

console.log(chunk([1,2,3], 2));


9

এই https://www.npmjs.com/package/array.chunk এর জন্য একটি এনএমপি প্যাকেজ তৈরি করেছে

var result = [];

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

টাইপড্রাই ব্যবহার করার সময়

var result = [];

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

@ A1rPun আমার খারাপ, আমি সেখানে মন্তব্য যুক্ত করিনি। হ্যাঁ, এর জন্য কোনও sliceপদ্ধতি নেই TypedArray, আমরা এর subarrayপরিবর্তে বিকাশকারী
موজিলা.আর.ইন- ইউএস

8

আপনি যদি ইকামাস্ক্রিপ্ট সংস্করণ> = 5.1 ব্যবহার করেন তবে আপনি অ্যারে.রেডুস () এর ও (এন) জটিলতা chunk()ব্যবহার করে একটি কার্যকরী সংস্করণ প্রয়োগ করতে পারেন :

function chunk(chunkSize, array) {
    return array.reduce(function(previous, current) {
        var chunk;
        if (previous.length === 0 || 
                previous[previous.length -1].length === chunkSize) {
            chunk = [];   // 1
            previous.push(chunk);   // 2
        }
        else {
            chunk = previous[previous.length -1];   // 3
        }
        chunk.push(current);   // 4
        return previous;   // 5
    }, []);   // 6
}

console.log(chunk(2, ['a', 'b', 'c', 'd', 'e']));
// prints [ [ 'a', 'b' ], [ 'c', 'd' ], [ 'e' ] ]

// nbrউপরের প্রতিটি ব্যাখ্যা :

  1. পূর্ববর্তী মান, অর্থাত্ পূর্ববর্তী অংশগুলির খালি খালি বা শেষের অংশে chunkSizeআইটেম থাকলে একটি নতুন অংশ তৈরি করুন
  2. বিদ্যমান অংশগুলির অ্যারেতে নতুন অংশটি যুক্ত করুন
  3. অন্যথায়, বর্তমান অংশটি খণ্ডগুলির অ্যারের শেষ অংশ
  4. খণ্ডে বর্তমান মান যুক্ত করুন
  5. খণ্ডগুলির পরিবর্তিত অ্যারেটি ফিরিয়ে দিন
  6. একটি খালি অ্যারে পাস করে হ্রাস শুরু করুন

এর উপর ভিত্তি করে কার্পিং chunkSize:

var chunk3 = function(array) {
    return chunk(3, array);
};

console.log(chunk3(['a', 'b', 'c', 'd', 'e']));
// prints [ [ 'a', 'b', 'c' ], [ 'd', 'e' ] ]

আপনি chunk()গ্লোবাল Arrayঅবজেক্টে ফাংশনটি যুক্ত করতে পারেন :

Object.defineProperty(Array.prototype, 'chunk', {
    value: function(chunkSize) {
        return this.reduce(function(previous, current) {
            var chunk;
            if (previous.length === 0 || 
                    previous[previous.length -1].length === chunkSize) {
                chunk = [];
                previous.push(chunk);
            }
            else {
                chunk = previous[previous.length -1];
            }
            chunk.push(current);
            return previous;
        }, []);
    }
});

console.log(['a', 'b', 'c', 'd', 'e'].chunk(4));
// prints [ [ 'a', 'b', 'c' 'd' ], [ 'e' ] ]


7
in coffeescript:

b = (a.splice(0, len) while a.length)

demo 
a = [1, 2, 3, 4, 5, 6, 7]

b = (a.splice(0, 2) while a.length)
[ [ 1, 2 ],
  [ 3, 4 ],
  [ 5, 6 ],
  [ 7 ] ]

a.splice (0, 2) a থেকে একটি [0.1] এর সাববারে সরিয়ে এবং সাববারাকে a [0..1] প্রদান করে। আমি সেই সমস্ত অ্যারের একটি অ্যারে তৈরি করছি
অর্পিত জৈন

2
আমি স্প্লাইস () এর পরিবর্তে অ-ধ্বংসাত্মক স্লাইস () পদ্ধতিটি ব্যবহার করার পরামর্শ দিচ্ছি
অ্যাশ ব্লু

7
results = []
chunk_size = 10
while(array.length > 0){
   results.push(array.splice(0, chunk_size))
}

1
কেন এটিকে নিচে ভোট দেওয়া হয়েছে তা নিশ্চিত নয়, তবে কোডটি কিছু ব্যাখ্যা ব্যবহার করতে পারে।
jpaugh

2
কারণ স্প্লাইস মূল অ্যারের জন্য ধ্বংসাত্মক।
ধাতব

7

নিম্নলিখিত ES2015 পদ্ধতির কোনও ফাংশন সংজ্ঞায়িত না করে এবং সরাসরি বেনামে অ্যারে (উদাহরণস্বরূপ অংশ 2 সহ) কাজ করে:

[11,22,33,44,55].map((_, i, all) => all.slice(2*i, 2*i+2)).filter(x=>x.length)

আপনি যদি এর জন্য কোনও ফাংশন সংজ্ঞায়িত করতে চান তবে আপনি এটি নিম্নলিখিত হিসাবে এটি করতে পারেন ( ব্লেজেমনজারের উত্তর সম্পর্কে কে ._-এর মন্তব্যে উন্নতি ):

const array_chunks = (array, chunk_size) => array
    .map((_, i, all) => all.slice(i*chunk_size, (i+1)*chunk_size))
    .filter(x => x.length)

6

এবং এটি এই বিষয়ে আমার অবদান হবে। আমার ধারণা .reduce()সেরা উপায় way

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);
        res = segment(arr,7);
console.log(JSON.stringify(res));

তবে উপরোক্ত বাস্তবায়ন খুব কার্যকরী নয় যেহেতু .reduce()সমস্ত arrফাংশন দিয়ে চলে । আরও কার্যকর পদ্ধতির (দ্রুততম জরুরী সমাধানের খুব কাছাকাছি) হ'ল, হ্রাসযুক্ত (অচল করে দেওয়া) অ্যারের উপর পুনরুক্তি করা যেহেতু আমরা এর আকারটি আগেই গণনা করতে পারি Math.ceil(arr/n);। আমাদের কাছে একবার খালি ফলাফলের অ্যারে থাকলে Array(Math.ceil(arr.length/n)).fill();বাকীটি এর মতো arrঅ্যারের স্লাইসগুলি ম্যাপ করা।

function chunk(arr,n){
  var r = Array(Math.ceil(arr.length/n)).fill();
  return r.map((e,i) => arr.slice(i*n, i*n+n));
}

arr = Array.from({length: 31},(_,i) => i+1);
res = chunk(arr,7);
console.log(JSON.stringify(res));



4

একটি কার্যকরী সমাধানের জন্য, রামদা ব্যবহার করে :

popularProductsআপনার ইনপুট অ্যারে কোথায় , 5খণ্ড আকার হয়

import splitEvery from 'ramda/src/splitEvery'

splitEvery(5, popularProducts).map((chunk, i) => {
// do something with chunk

})


4

ES6 এক লাইন পদ্ধতির উপর ভিত্তি করে Array.prototype reduceএবং pushপদ্ধতি:

const doChunk = (list, size) => list.reduce((r, v) =>
  (!r.length || r[r.length - 1].length === size ?
    r.push([v]) : r[r.length - 1].push(v)) && r
, []);

console.log(doChunk([0,1,2,3,4,5,6,7,8,9,10,11,12], 5));
// [[0, 1, 2, 3, 4], [5, 6, 7, 8, 9], [10, 11, 12]]

4

ES6 জেনারেটর সংস্করণ

function* chunkArray(array,size=1){
    var clone = array.slice(0);
    while (clone.length>0) 
      yield clone.splice(0,size); 
};
var a = new Array(100).fill().map((x,index)=>index);
for(const c of chunkArray(a,10)) 
    console.log(c);

constপরিবর্তে ব্যবহার করুন।
20 Ван

4

এটি আমি সবচেয়ে কার্যকর এবং সোজা-এগিয়ে সমাধান সমাধান হিসাবে ভাবতে পারি:

function chunk(array, chunkSize) {
    let chunkCount = Math.ceil(array.length / chunkSize);
    let chunks = new Array(chunkCount);
    for(let i = 0, j = 0, k = chunkSize; i < chunkCount; ++i) {
        chunks[i] = array.slice(j, k);
        j = k;
        k += chunkSize;
    }
    return chunks;
}

4

ES6 ক্রিয়াকলাপে # মায়া #ftw ছড়িয়ে পড়ে

const chunk =
  (size, xs) => 
    xs.reduce(
      (segments, _, index) =>
        index % size === 0 
          ? [...segments, xs.slice(index, index + size)] 
          : segments, 
      []
    );

console.log( chunk(3, [1, 2, 3, 4, 5, 6, 7, 8]) );


4

এখানে একটি পুনরাবৃত্তির সমাধান যা টেল কল অনুকূলিতকরণ।

const splitEvery = (n, xs, y=[]) =>
  xs.length===0 ? y : splitEvery(n, xs.slice(n), y.concat([xs.slice(0, n)])) 

console.log(splitEvery(2, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]))


4

আরও একটি সমাধান ব্যবহার করে arr.reduce():

const chunk = (arr, size) => (
  arr.reduce((acc, _, i) => {
    if (i % size === 0) acc.push(arr.slice(i, i + size))
    return acc
  }, [])
)

// Usage:
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
const chunked = chunk(numbers, 3)
console.log(chunked)

এই সমাধানটি স্টিভ হলগাদোর সমাধানের সাথে খুব মিল । তবে, কারণ এই দ্রবণটি অ্যারে ছড়িয়ে পড়া ব্যবহার করে না এবং হ্রাসকারক ফাংশনে নতুন অ্যারে তৈরি করে না, এটি দ্রুত ( জেসপ্রুফ পরীক্ষা দেখুন ) এবং অন্যান্য সমাধানের চেয়ে বিষয়গতভাবে আরও পঠনযোগ্য (সরল বাক্য গঠন)।

প্রতি নবম পুনরাবৃত্তিতে (যেখানে এন = size; প্রথম পুনরাবৃত্তি থেকে শুরু হয়), সঞ্চায়ক অ্যারে ( acc) অ্যারে ( ) এর একটি অংশের সাথে সংযুক্ত করা হয় arr.slice(i, i + size)এবং তারপরে ফিরে আসে। অন্যান্য পুনরাবৃত্তিতে, সঞ্চয়ের অ্যারে যেমন হয় তেমন ফিরে আসে।

যদি sizeশূন্য হয়, পদ্ধতিটি একটি খালি অ্যারে প্রদান করে। যদি sizeনেতিবাচক হয়, পদ্ধতিটি ভাঙ্গা ফলাফল দেয়। সুতরাং, আপনার ক্ষেত্রে যদি প্রয়োজন হয় তবে আপনি নেতিবাচক বা অ-ধনাত্মক sizeমান সম্পর্কে কিছু করতে চাইতে পারেন ।


যদি গতি আপনার ক্ষেত্রে গুরুত্বপূর্ণ হয় তবে একটি সাধারণ forলুপ ব্যবহারের চেয়ে দ্রুত হবে arr.reduce()( jscreen পরীক্ষা দেখুন ) এবং কেউ কেউ এই স্টাইলটিকে আরও পঠনযোগ্যও দেখতে পাবেন:

function chunk(arr, size) {
  // This prevents infinite loops
  if (size < 1) throw new Error('Size must be positive')

  const result = []
  for (let i = 0; i < arr.length; i += size) {
    result.push(arr.slice(i, i + size))
  }
  return result
}

2

সম্পাদনা: @ mblase75 আমি আমার লেখার সময় পূর্বের উত্তরে আরও সংক্ষিপ্ত কোড যুক্ত করেছি, সুতরাং আমি তার সমাধানটি দিয়ে যাওয়ার পরামর্শ দিই।

আপনি এই জাতীয় কোড ব্যবহার করতে পারেন:

var longArray = ["Element 1","Element 2","Element 3", /*...*/];
var smallerArrays = []; // will contain the sub-arrays of 10 elements each
var arraySize = 10;
for (var i=0;i<Math.ceil(longArray.length/arraySize);i++) {
    smallerArrays.push(longArray.slice(i*arraySize,i*arraySize+arraySize));
}

arraySizeছোট অ্যারের সর্বাধিক দৈর্ঘ্য পরিবর্তন করতে এর মানটি পরিবর্তন করুন।


2

এখানে কেবল পুনরাবৃত্তি এবং স্লাইস () ব্যবহার করে একটি নন-মিউটরিং সমাধান।

const splitToChunks = (arr, chunkSize, acc = []) => (
    arr.length > chunkSize ?
        splitToChunks(
            arr.slice(chunkSize),
            chunkSize,
            [...acc, arr.slice(0, chunkSize)]
        ) :
        [...acc, arr]
);

তারপরে এটি splitToChunks([1, 2, 3, 4, 5], 3)পেতে পছন্দ করুন [[1, 2, 3], [4, 5]]

আপনার চেষ্টা করার জন্য এখানে একটি মূর্খতা রয়েছে: https://jsfiddle.net/6wtrbx6k/2/

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.