অ্যারেগুলির একটি অ্যারে মার্জ / ফ্ল্যাট করুন


1104

আমার কাছে একটি জাভাস্ক্রিপ্ট অ্যারে রয়েছে:

[["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"]]

আমি কীভাবে পৃথক অভ্যন্তরীণ অ্যারেগুলিকে একের মধ্যে একীভূত করতে যাব:

["$6", "$12", "$25", ...]

gist.github.com/Nishchit14/4c6a7349b3c778f7f97b912629a9f228 এই লিঙ্কটি ES5 এবং ES6 সমতল বর্ণনা করে
নিশ্চিত ধনানী

17
যে সমস্ত সমাধান reduce+ ব্যবহার করে তার সবগুলি concatহ'ল হ'ল ((এন / 2) / 2) যেখানে কোনও স্বীকৃত উত্তর হিসাবে (কেবলমাত্র একটি কল concat) খারাপ ব্রাউজারে সর্বাধিক ও (এন * 2) হবে এবং একটিতে ও (এন) হবে ভাল একটা. এছাড়াও Denys সমাধান দ্রুত একক চেয়ে 2x প্রকৃত প্রশ্নের জন্য এবং পর্যন্ত অপ্টিমাইজ করা হয় concat। জন্য reduceএটা মজা শীতল ক্ষুদ্র কোড লেখা কিন্তু উদাহরণস্বরূপ মনে ভাবেন যদি অ্যারের ছিল 1000 এক উপাদান subarrays সব কমাতে + + CONCAT সমাধান কাজ করা হবে 500500 অপারেশন যেখানে একক CONCAT বা সহজ লুপ 1000 অপারেশন করতে হবে না।
gman

11
কেবল ব্যবহারকারী স্প্রেড অপারেটর[].concat(...array)
ওলেগ ডাটার

@gman কীভাবে হ'ল + কনক্যাট দ্রবণ O ((N ^ 2) / 2)? stackoverflow.com/questions/52752666/… একটি ভিন্ন জটিলতার কথা উল্লেখ করে।
উসমান

3
ES2019 সমর্থন করে সর্বশেষতম ব্রাউজারগুলির সাথে : array.flat(Infinity)যেখানে Infinityসমতল করার সর্বোচ্চ গভীরতা।
টিমোথি গু

উত্তর:


1860

আপনি concatঅ্যারেগুলিকে মার্জ করতে ব্যবহার করতে পারেন :

var arrays = [
  ["$6"],
  ["$12"],
  ["$25"],
  ["$25"],
  ["$18"],
  ["$22"],
  ["$10"]
];
var merged = [].concat.apply([], arrays);

console.log(merged);

এর applyপদ্ধতিটি ব্যবহার করে concatকেবল দ্বিতীয় প্যারামিটারটিকে অ্যারে হিসাবে নেওয়া হবে, তাই শেষ লাইনটি এটির মতোই:

var merged2 = [].concat(["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"]);

এছাড়াও Array.prototype.flat()পদ্ধতিটি (ES2019 এ প্রবর্তিত) রয়েছে যা আপনি অ্যারেগুলি সমতল করার জন্য ব্যবহার করতে পারেন, যদিও এটি কেবল নোড.জেসগুলিতে 11 সংস্করণ 11 দিয়ে শুরু হয় এবং এটি ইন্টারনেট এক্সপ্লোরার-এ মোটেই নয়

const arrays = [
      ["$6"],
      ["$12"],
      ["$25"],
      ["$25"],
      ["$18"],
      ["$22"],
      ["$10"]
    ];
const merge3 = arrays.flat(1); //The depth level specifying how deep a nested array structure should be flattened. Defaults to 1.
console.log(merge3);
    


10
নোট যে concatউত্স অ্যারে পরিবর্তন করে না, তাই mergedঅ্যারে কল করার পরে ফাঁকা থাকবে concat। ভাল পছন্দ কিছু বলতে:merged = merged.concat.apply(merged, arrays);
Nate

65
var merged = [].concat.apply([], arrays);এটি এক লাইনে পাওয়ার জন্য ভাল কাজ করছে বলে মনে হচ্ছে। সম্পাদনা: নিকিতার উত্তর ইতিমধ্যে দেখায়।
শান

44
বা Array.prototype.concat.apply([], arrays)
ড্যানহবার

30
দ্রষ্টব্য: এই উত্তরটি কেবলমাত্র এক স্তর গভীর করে তুলবে। পুনরাবৃত্ত সমতলতার জন্য @ ত্রিনডাজের উত্তর দেখুন।
ফ্রোগজ

208
@ শানের মন্তব্যে আরও: ES6 সিনট্যাক্সটি এই সুপার সংক্ষিপ্ত করে তোলে:var merged = [].concat(...arrays)
শেঠি

505

এখানে একটি সংক্ষিপ্ত ফাংশন যা কোনও এন-ডাইমেনশনাল অ্যারে সমতল করতে নতুন কিছু জাভাস্ক্রিপ্ট অ্যারে পদ্ধতি ব্যবহার করে।

function flatten(arr) {
  return arr.reduce(function (flat, toFlatten) {
    return flat.concat(Array.isArray(toFlatten) ? flatten(toFlatten) : toFlatten);
  }, []);
}

ব্যবহার:

flatten([[1, 2, 3], [4, 5]]); // [1, 2, 3, 4, 5]
flatten([[[1, [1.1]], 2, 3], [4, 5]]); // [1, 1.1, 2, 3, 4, 5]

17
আমি এই পদ্ধতির পছন্দ। এটি আরও সাধারণ এবং নেস্টেড অ্যারেগুলিকে সমর্থন করে
আলফ্রেডকম্বের

10
এই সমাধানের জন্য মেমরির ব্যবহারের প্রোফাইলটি কী? দেখে মনে হচ্ছে এটি লেজ পুনরাবৃত্তির সময় প্রচুর মধ্যবর্তী অ্যারে তৈরি করে ....
জেবিআর উইলকিনসন

7
@ হাইজয়, এটি হ্রাস কার্যকারিতার জন্য প্রারম্ভিক সঞ্চয়ের মান, যা এমডনিকে প্রাথমিক মান বলে। এই ক্ষেত্রে এটি এর মান flatবেনামী ফাংশন প্রেরণ করা প্রথম কলে reduce। যদি এটি নির্দিষ্ট না করা হয়, তবে প্রথম কলটি reduceঅ্যারের বাইরে প্রথম মানটিকে আবদ্ধ করে flat, যা পরিণামে উভয় উদাহরণে 1আবদ্ধ হতে পারে flat1.concatকোন কাজ নয়।
নোহ ফ্রেইটাস

19
বা একটি সংক্ষিপ্ততর, const flatten = (arr) => arr.reduce((flat, next) => flat.concat(next), []);
যৌনতর

12
স্বেচ্ছাসেবীর বাসা বাঁধার জন্য সোনাভ এবং নোহের সমাধানগুলিতে রিফিং:const flatten = (arr) => arr.reduce((flat, next) => flat.concat(Array.isArray(next) ? flatten(next) : next), []);
হবে

314

একটি বিভ্রান্তিকরভাবে লুকানো পদ্ধতি রয়েছে, যা আসলটি পরিবর্তন না করে একটি নতুন অ্যারে তৈরি করে:

var oldArray = [[1],[2,3],[4]];
var newArray = Array.prototype.concat.apply([], oldArray);
console.log(newArray); // [ 1, 2, 3, 4 ]


11
CoffeeScript এই হল[].concat([[1],[2,3],[4]]...)
amoebe

8
@ উত্তর আপনার [[1],[2,3],[4]]ফলাফল হিসাবে ফলাফল দেয় । @ নিকিতা যে সমাধানটি দেয় তা কফিস্ক্রিপ্টের পাশাপাশি জেএসের পক্ষেও সঠিক।
রায়ান কেনেডি

5
আহ, আমি আপনার ত্রুটি খুঁজে পেয়েছি। আপনার স্বরলিখনটিতে আপনার অতিরিক্ত জোড়া বর্গাকার বন্ধনী রয়েছে, হওয়া উচিত [].concat([1],[2,3],[4],...)
রায়ান কেনেডি

21
আমি মনে করি আপনার ত্রুটিটিও পেয়েছি। ...প্রকৃত কোড, না কিছু ঊহ্য শব্দ বিন্দু আছে।
অ্যামিবি

3
লাইব্রেরির ফাংশনটি ব্যবহার করার অর্থ এই নয় যে কোনও কম জরুরী "গণ্ডগোল" আছে there's ঠিক যে লাইব্রেরির মধ্যেই এই জগাখিচুড়ি লুকানো আছে। স্পষ্টতই আপনার নিজের ফাংশন ঘূর্ণায়মানের চেয়ে গ্রন্থাগারটি ব্যবহার করা ভাল, তবে দাবি করা যে এই কৌশলটি "অপরিহার্য জগাখিচুড়ি" হ্রাস করেছে এটি বেশ নির্বোধ।
পলদীপাইন্ড

204

এটি জাভাস্ক্রিপ্ট হ্রাস ফাংশন দ্বারা সেরা করা যেতে পারে।

var arrays = [["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"], ["$0"], ["$15"],["$3"], ["$75"], ["$5"], ["$100"], ["$7"], ["$3"], ["$75"], ["$5"]];

arrays = arrays.reduce(function(a, b){
     return a.concat(b);
}, []);

অথবা, ES2015 সহ:

arrays = arrays.reduce((a, b) => a.concat(b), []);

JS-বেহালার

মজিলা ডক্স


1
@ জনস আসলে প্রকৃতপক্ষে একক (অ্যারে) পরিবর্তনের পরিবর্তে ফিডগুলি কমিয়ে দিন। প্রুফ? () কমিয়ে আনে এবং দেখুন এটি কার্যকর হয় কিনা। হ্রাস () এখানে Function.prototype.apply ()
আন্দ্রে ওয়ার্ল্যাং

3
আমি হ্রাসও ব্যবহার করতে পারতাম তবে এই স্নিপেট থেকে আমি একটি আকর্ষণীয় বিষয় শিখেছি যে বেশিরভাগ সময় আপনাকে প্রাথমিক মান পাস করতে হবে না :)
জোসে এফ রোমানিলো

2
হ্রাস করার সমস্যাটি হ'ল অ্যারেটি খালি থাকতে পারে না, তাই আপনাকে অতিরিক্ত বৈধতা যুক্ত করতে হবে।
ক্যালবার্টস

4
@ ক্যালবার্টস কেবলমাত্র প্রাথমিক মানটি পাস করুন []এবং কোনও বৈধকরণের প্রয়োজন নেই।

7
যেহেতু আপনি ES6 ব্যবহার করেন তাই আপনি স্প্রেড-অপারেটরটিকে অ্যারে আক্ষরিক হিসাবেও ব্যবহার করতে পারেন । arrays.reduce((flatten, arr) => [...flatten, ...arr])
পুটজি সান

108

এটি করার জন্য ফ্ল্যাট নামে একটি নতুন নেটিভ পদ্ধতি রয়েছে ।

(2019 সালের শেষের দিকে, flatএখন ইসিএমএ 2019 স্ট্যান্ডার্ডে প্রকাশিত হয়েছে, এবং core-js@3(বাবেলের লাইব্রেরি ) এটি তাদের পলিফিল লাইব্রেরিতে অন্তর্ভুক্ত করেছে )

const arr1 = [1, 2, [3, 4]];
arr1.flat(); 
// [1, 2, 3, 4]

const arr2 = [1, 2, [3, 4, [5, 6]]];
arr2.flat();
// [1, 2, 3, 4, [5, 6]]

// Flatten 2 levels deep
const arr3 = [2, 2, 5, [5, [5, [6]], 7]];
arr3.flat(2);
// [2, 2, 5, 5, 5, [6], 7];

// Flatten all levels
const arr4 = [2, 2, 5, [5, [5, [6]], 7]];
arr4.flat(Infinity);
// [2, 2, 5, 5, 5, 6, 7];

4
এটি লজ্জাজনক এটি উত্তরগুলির প্রথম পৃষ্ঠায়ও নেই। এই বৈশিষ্ট্যটি ক্রোম 69 এবং ফায়ারফক্স 62 এ উপলব্ধ রয়েছে (এবং ব্যাকএন্ডে যারা কাজ করছেন তাদের নোড 11)
ম্যাট এম।


2
-1; না, এটি ECMAScript 2018 এর অংশ নয় । এটি এখনও কেবলমাত্র একটি প্রস্তাব যা এটি কোনও ইসমাস্ক্রিপ্ট বিশেষায় তৈরি করে নি।
মার্ক অ্যামেরি

1
আমি মনে করি এখন আমরা এটি বিবেচনা করতে পারি .. কারণ এখন এটি স্ট্যান্ডার্ডের অংশ (2019) .. আমরা কি এর পারফরম্যান্স অংশটি আবার একবার ঘুরে দেখতে পারি?
যুবরাজ

দেখে মনে হচ্ছে এটি এখনও কোনও মাইক্রোসফ্ট ব্রাউজার দ্বারা সমর্থিত নয় (অন্তত আমি এই মন্তব্যটি লেখার সময়)
লরেন্ট এস

78

এখানে বেশিরভাগ উত্তর বিশাল (যেমন 200,000 উপাদান) অ্যারেগুলিতে কাজ করে না এবং এমনকি যদি তা করে তবে সেগুলি ধীর হয়। polkovnikov.ph- এর উত্তরে সেরা পারফরম্যান্স রয়েছে তবে এটি গভীর সমতলকরণের জন্য কাজ করে না।

এখানে দ্রুততম সমাধানটি দেওয়া হয়েছে, যা নীড়ের একাধিক স্তরের সাথে অ্যারেতেও কাজ করে :

const flatten = function(arr, result = []) {
  for (let i = 0, length = arr.length; i < length; i++) {
    const value = arr[i];
    if (Array.isArray(value)) {
      flatten(value, result);
    } else {
      result.push(value);
    }
  }
  return result;
};

উদাহরণ

বিশাল অ্যারে

flatten(Array(200000).fill([1]));

এটি ঠিক জরিমানা বিশাল অ্যারে পরিচালনা করে। আমার মেশিনে এই কোডটি কার্যকর করতে প্রায় 14 এমএস লাগে।

নেস্টেড অ্যারে

flatten(Array(2).fill(Array(2).fill(Array(2).fill([1]))));

এটি নেস্টেড অ্যারেগুলির সাথে কাজ করে। এই কোড উত্পাদন করে [1, 1, 1, 1, 1, 1, 1, 1]

বিভিন্ন স্তরের বাসা বাঁধে অ্যারে

flatten([1, [1], [[1]]]);

এটির মতো চ্যাপ্টা অ্যারেতে কোনও সমস্যা নেই।


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

@ সর্বদা কিন্তু কোন বাস্তব-বিশ্বের পরিস্থিতিতে আপনার কয়েক স্তরের বাসা বাঁধতে হবে?
মিশা পেরেকোভস্কি

2
সাধারণত, যখন অ্যারেটি ব্যবহারকারী উত্পন্ন সামগ্রী থেকে তৈরি হয়।
nitely

@ 0xcaff Chrome এ এটি 200 000-উপাদান অ্যারে (আপনি পেয়েছেন RangeError: Maximum call stack size exceeded) দিয়ে মোটেও কাজ করে না । 20 000-উপাদান অ্যারের জন্য এটি 2-5 মিলিসেকেন্ড নেয় takes
মিশা পেরেকোভস্কি

3
ও এর স্বরলিপি জটিলতা কি?
জর্জ ক্যাটসানোস

58

আপডেট: দেখা গেছে যে এই সমাধানটি বড় অ্যারে দিয়ে কাজ করে না। এটি আপনি একটি ভাল, দ্রুত সমাধান খুঁজছেন, খুঁজে বার করো এই উত্তর


function flatten(arr) {
  return [].concat(...arr)
}

কেবল প্রসারিত হয় arrএবং এটিকে আর্গুমেন্ট হিসাবে প্রেরণ করে concat()যা সমস্ত অ্যারেগুলিকে এক করে দেয়। এর সমতুল্য [].concat.apply([], arr)

আপনি গভীর সমতলকরণের জন্য এটি ব্যবহার করে দেখতে পারেন:

function deepFlatten(arr) {
  return flatten(           // return shalowly flattened array
    arr.map(x=>             // with each x in array
      Array.isArray(x)      // is x an array?
        ? deepFlatten(x)    // if yes, return deeply flattened x
        : x                 // if no, return just x
    )
  )
}

জেএসবিনে ডেমো দেখুন ।

এই উত্তরে ব্যবহৃত ECMAScript 6 টি উপাদানের জন্য রেফারেন্স:


পার্শ্ব নোট: পদ্ধতিগুলি find()এবং অ্যারো ফাংশনগুলি সমস্ত ব্রাউজার দ্বারা সমর্থিত নয়, তবে এর অর্থ এই নয় যে আপনি এই বৈশিষ্ট্যগুলি এখনই ব্যবহার করতে পারবেন না। কেবল ব্যাবেল ব্যবহার করুন - এটি ES6 কোডটি ES5 তে রূপান্তর করে।


কারণ এখানে প্রায় সমস্ত উত্তর applyএইভাবে অপব্যবহার করে, আমি আমার মন্তব্যগুলি আপনার কাছ থেকে সরিয়েছি। আমি এখনও মনে করি applyএইভাবে ব্যবহার করা / ছড়িয়ে দেওয়া খারাপ পরামর্শ, তবে যেহেতু কেউই

@ LUH3417 এটি এমন নয়, আমি আপনার মন্তব্যের সত্যই প্রশংসা করি। দেখা গেল আপনি ঠিক বলেছেন - এই সমাধানটি বড় অ্যারে দিয়ে কাজ করে না। আমি আরেকটি উত্তর পোস্ট করেছি যা 200,000 উপাদানগুলির অ্যারে দিয়েও সূক্ষ্ম কাজ করে।
মিশা পেরেকোভস্কি

আপনি যদি ES6 ব্যবহার করে থাকেন তবে আপনি আরও const flatten = arr => [].concat(...arr)
কমিয়ে নিতে

"বড় অ্যারে দিয়ে কাজ করে না" এর অর্থ কী? কত বড়? কি ঘটেছে?
জেমি

4
@ জেমি উদাহরণস্বরূপ এই পদ্ধতিটি ব্যবহার করে 500000-উপাদান অ্যারে সমতল করার চেষ্টা করে "রেঞ্জেরর: সর্বাধিক কল স্ট্যাকের আকার ছাড়িয়ে গেছে"।
মিশা পেরেকোভস্কি

51

আপনি অ্যান্ডস্কোর ব্যবহার করতে পারেন :

var x = [[1], [2], [3, 4]];

_.flatten(x); // => [1, 2, 3, 4]

20
ওহো, কেউ পার্সকে জেএসে যুক্ত করেছে? :-)
জেবিআরউইলকিনসন

9
@ জেবিআরওয়িলকিনসন সম্ভবত জেএস আপনাকে গ্রেট গুডের জন্য একটি হাস্কেল শিখতে চায় !?
স্টাইফলে

1+ - আপনি দ্বিতীয় আর্গুমেন্টের জন্য নির্দিষ্ট করেtrue একটি অগভীর চ্যাপ্টা অ্যারেও নির্দিষ্ট করতে পারেন ।
জোশ ক্রোজিয়ার

7
@ স্টাইফেলের মন্তব্য সম্পর্কিত সম্পূর্ণতার স্বার্থে: learnyouahaskell.com
সাইমন এ। ইউগস্টার

41

জেনেরিক পদ্ধতিগুলির অর্থ প্রতিবার যখন আমাদের একটি নির্দিষ্ট আচরণ ব্যবহার করার প্রয়োজন হয় তখন আমাদের জটিলতা আবার লিখতে হবে না।

concatMap(বা flatMap) এই পরিস্থিতিতে আমাদের যা প্রয়োজন তা হ'ল।

// concat :: ([a],[a]) -> [a]
const concat = (xs,ys) =>
  xs.concat (ys)

// concatMap :: (a -> [b]) -> [a] -> [b]
const concatMap = f => xs =>
  xs.map(f).reduce(concat, [])

// id :: a -> a
const id = x =>
  x

// flatten :: [[a]] -> [a]
const flatten =
  concatMap (id)

// your sample data
const data =
  [["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"]]

console.log (flatten (data))

দূরদর্শিতা

এবং হ্যাঁ, আপনি এটি সঠিকভাবে অনুমান করেছিলেন, এটি কেবলমাত্র একটি স্তরকে সমতল করে তোলে, এটি ঠিক কীভাবে কাজ করা উচিত

এরকম কিছু ডেটা সেট কল্পনা করুন

// Player :: (String, Number) -> Player
const Player = (name,number) =>
  [ name, number ]

// team :: ( . Player) -> Team
const Team = (...players) =>
  players

// Game :: (Team, Team) -> Game
const Game = (teamA, teamB) =>
  [ teamA, teamB ]

// sample data
const teamA =
  Team (Player ('bob', 5), Player ('alice', 6))

const teamB =
  Team (Player ('ricky', 4), Player ('julian', 2))

const game =
  Game (teamA, teamB)

console.log (game)
// [ [ [ 'bob', 5 ], [ 'alice', 6 ] ],
//   [ [ 'ricky', 4 ], [ 'julian', 2 ] ] ]

ঠিক আছে, এখন বলুন আমরা এমন একটি রোস্টার মুদ্রণ করতে চাই যাতে এতে অংশ নেওয়া সমস্ত খেলোয়াড় দেখায় game...

const gamePlayers = game =>
  flatten (game)

gamePlayers (game)
// => [ [ 'bob', 5 ], [ 'alice', 6 ], [ 'ricky', 4 ], [ 'julian', 2 ] ]

যদি আমাদের flattenপদ্ধতিটি নেস্টেড অ্যারেগুলিকেও সমতল করে তোলে, তবে আমরা এই আবর্জনার ফলাফলটি শেষ করব ...

const gamePlayers = game =>
  badGenericFlatten(game)

gamePlayers (game)
// => [ 'bob', 5, 'alice', 6, 'ricky', 4, 'julian', 2 ]

রোলিন গভীর, বাবু

এটি কখনও কখনও আপনি নেস্টেড অ্যারেগুলিও সমতল করতে চান না তা বলার অপেক্ষা রাখে না - কেবল এটিই ডিফল্ট আচরণ নয় should

আমরা সহজেই একটি deepFlattenপদ্ধতি তৈরি করতে পারি …

// concat :: ([a],[a]) -> [a]
const concat = (xs,ys) =>
  xs.concat (ys)

// concatMap :: (a -> [b]) -> [a] -> [b]
const concatMap = f => xs =>
  xs.map(f).reduce(concat, [])

// id :: a -> a
const id = x =>
  x

// flatten :: [[a]] -> [a]
const flatten =
  concatMap (id)

// deepFlatten :: [[a]] -> [a]
const deepFlatten =
  concatMap (x =>
    Array.isArray (x) ? deepFlatten (x) : x)

// your sample data
const data =
  [0, [1, [2, [3, [4, 5], 6]]], [7, [8]], 9]

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

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

সেখানে। এখন প্রতিটি কাজের জন্য আপনার কাছে একটি সরঞ্জাম রয়েছে - একটি স্তরের বাসা বাঁধার জন্য একটি flattenএবং সমস্ত বাসা বেঁধে দেওয়ার জন্য একটিdeepFlatten

হতে পারে আপনি এটি কল করতে পারেন obliterateবা nukeআপনি নামের মত না deepFlatten


দু'বার পুনরাবৃত্তি করবেন না!

অবশ্যই উপরের প্রয়োগগুলি চতুর এবং সংক্ষিপ্ত, তবে .mapএকটি কল অনুসরণ করে ব্যবহার করে.reduce আমরা এটি প্রয়োজনের চেয়ে আরও বেশি পুনরাবৃত্তি করছি

আমি যে বিশ্বস্ত সমন্বয়কারীকে ফোন করছি তা ব্যবহার mapReduceকরে পুনরাবৃত্তিগুলি একটি মিনিমে রাখতে সহায়তা করে; এটি একটি ম্যাপিং ফাংশন নেয় m :: a -> b, একটি হ্রাসকরণ ফাংশন r :: (b,a) ->bএবং একটি নতুন হ্রাসকরণ ফাংশন ফিরিয়ে দেয় - এই সংযোজকটি ট্রান্সডুসারদের কেন্দ্রে রয়েছে ; আপনি যদি আগ্রহী হন তবে আমি সেগুলি সম্পর্কে অন্যান্য উত্তর লিখেছি

// mapReduce = (a -> b, (b,a) -> b, (b,a) -> b)
const mapReduce = (m,r) =>
  (acc,x) => r (acc, m (x))

// concatMap :: (a -> [b]) -> [a] -> [b]
const concatMap = f => xs =>
  xs.reduce (mapReduce (f, concat), [])

// concat :: ([a],[a]) -> [a]
const concat = (xs,ys) =>
  xs.concat (ys)

// id :: a -> a
const id = x =>
  x

// flatten :: [[a]] -> [a]
const flatten =
  concatMap (id)
  
// deepFlatten :: [[a]] -> [a]
const deepFlatten =
  concatMap (x =>
    Array.isArray (x) ? deepFlatten (x) : x)

// your sample data
const data =
  [ [ [ 1, 2 ],
      [ 3, 4 ] ],
    [ [ 5, 6 ],
      [ 7, 8 ] ] ]

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

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


প্রায়শই, আমি যখন আপনার জবাবগুলি দেখি তখন আমি আমার প্রত্যাহার করতে চাই, কারণ সেগুলি মূল্যহীন হয়ে পড়েছে। দুর্দান্ত উত্তর! concatনিজেই স্ট্যাকটি ফুটিয়ে তোলে না, কেবল ...এবং applyকরে (খুব বড় অ্যারে সহ)। আমি তা দেখিনি। আমি এখনই ভয়ঙ্কর বোধ করছি।

@ LUH3417 আপনার ভয়ঙ্কর বোধ করা উচিত নয়। আপনি ভাল লিখিত ব্যাখ্যা সহ ভাল উত্তর প্রদান। এখানে সবকিছুই একটি শেখার অভিজ্ঞতা - আমি প্রায়শই ভুল করি এবং খারাপ উত্তরও লিখি। আমি কয়েক মাসের মধ্যে তাদের আবার ঘুরে দেখি এবং "wtf আমি কি ভাবছিলাম?" এবং সম্পূর্ণরূপে সংশোধিত জিনিসগুলি শেষ করুন। কোন উত্তর নিখুঁত। আমরা সকলেই কিছুটা শেখার বক্ররেখায় রয়েছি ^ _ ^
আপনাকে ধন্যবাদ

1
দয়া করে নোট করুন যে concatজাভাস্ক্রিপ্টে হাস্কেলের চেয়ে আলাদা অর্থ রয়েছে। হাস্কেলের concat( [[a]] -> [a]) flattenজাভাস্ক্রিপ্টে ডাকা হবে এবং এটি প্রয়োগ করা হয়েছে foldr (++) [](জাভাস্ক্রিপ্ট: foldr(concat) ([])ত্রিযুক্ত ফাংশন ধরে)। জাভাস্ক্রিপ্ট এর concatএকটি অদ্ভুত পরিশেষে যোগ (হয় (++)মধ্যে Haskell), যা উভয় সব ব্যবস্থা করতে সক্ষম [a] -> [a] -> [a]এবং a -> [a] -> [a]

আমার ধারণা একটি ভাল নাম ছিল flatMap, কারণ এটি concatMapহ'ল: মোনাডের bindউদাহরণ listconcatpMapহিসাবে বাস্তবায়ন করা হয় foldr ((++) . f) []। জাভাস্ক্রিপ্ট অনুবাদ করা: const flatMap = f => foldr(comp(concat) (f)) ([])। এই ছাড়া আপনার বাস্তবায়ন অনুরূপ অবশ্যই হয় comp

সেই অ্যালগরিদমের জটিলতা কী?
জর্জ ক্যাটসানোস

32

আপনার সাধারণ অ্যারেতে কিছু অ-অ্যারে উপাদান থাকতে পারে যখন আরও সাধারণ ক্ষেত্রে সমাধান।

function flattenArrayOfArrays(a, r){
    if(!r){ r = []}
    for(var i=0; i<a.length; i++){
        if(a[i].constructor == Array){
            r.concat(flattenArrayOfArrays(a[i], r));
        }else{
            r.push(a[i]);
        }
    }
    return r;
}

4
আপনি কোনও জসনপ্যাথ ক্যোয়ারী থেকে প্রাপ্ত ফলাফল-সেটগুলির নেস্টেড অ্যারে ফর্মকে সমতল করার ক্ষেত্রে এই পদ্ধতির খুব কার্যকর ছিল ।
কেভিনেঞ্জানজ

1
অ্যারে করার পদ্ধতি হিসাবে যুক্ত:Object.defineProperty(Array.prototype,'flatten',{value:function(r){for(var a=this,i=0,r=r||[];i<a.length;++i)if(a[i]!=null)a[i] instanceof Array?a[i].flatten(r):r.push(a[i]);return r}});
ফ্রোগজ

যদি আমরা ম্যানুয়ালি দ্বিতীয় যুক্তিতে পাস করি তবে এটি ভঙ্গ হবে। উদাহরণস্বরূপ, এটি চেষ্টা করুন: flattenArrayOfArrays (arr, 10)বা এটি flattenArrayOfArrays(arr, [1,[3]]);- সেই দ্বিতীয় যুক্তি আউটপুটটিতে যুক্ত করা হবে।
ওম শঙ্কর 19 ই

2
এই উত্তরটি সম্পূর্ণ নয়! পুনরাবৃত্তির ফলাফল কখনই কোথাও বরাদ্দ করা হয় না, তাই পুনরাবৃত্তির ফলাফলটি হারিয়ে যায়
r3wt

1
@ r3wt এগিয়ে গিয়ে একটি সংশোধন করেছে। আপনার যা করা দরকার তা নিশ্চিত হ'ল আপনি যে চলমান অ্যারেটি বজায় রেখেছেন rতা বাস্তবে পুনরাবৃত্তি থেকে ফলাফলগুলি সুস্পষ্ট করে তুলবে।
আগস্ট

29

reduce(callback[, initialValue])পদ্ধতি ব্যবহার সম্পর্কে কিJavaScript 1.8

list.reduce((p,n) => p.concat(n),[]);

চাকরী করত।


8
[[1], [2,3]].reduce( (a,b) => a.concat(b), [] )আরও সেক্সি হয়।
গোলাপট

5
আমাদের ক্ষেত্রে সহজ দ্বিতীয় [[1], [2,3]].reduce( (a,b) => a.concat(b))
তর্কটির প্রয়োজন নেই

29

কার্যকরী শৈলীতে আরও একটি ইসমাস্ক্রিপ্ট 6 সমাধান:

একটি ফাংশন ঘোষণা:

const flatten = arr => arr.reduce(
  (a, b) => a.concat(Array.isArray(b) ? flatten(b) : b), []
);

এবং এটি ব্যবহার করুন:

flatten( [1, [2,3], [4,[5,[6]]]] ) // -> [1,2,3,4,5,6]

 const flatten = arr => arr.reduce(
         (a, b) => a.concat(Array.isArray(b) ? flatten(b) : b), []
       );


console.log( flatten([1, [2,3], [4,[5],[6,[7,8,9],10],11],[12],13]) )

আধুনিক ব্রাউজারগুলির শেষ প্রকাশে উপলব্ধ একটি নেটিভ ফাংশন অ্যারে.প্রোটোটাইপ.ফ্ল্যাট () (ES6 এর জন্য প্রস্তাব ) বিবেচনা করুন । @ (Константин Ван) এবং @ (মার্ক আমেরি) কে ধন্যবাদ মন্তব্যগুলিতে এটি উল্লেখ করেছে।

flatফাংশন এক পরামিতি, এরে পাখির, যা সমান প্রত্যাশিত গভীরতা উল্লেখ রয়েছে 1ডিফল্টরূপে।

[1, 2, [3, 4]].flat();                  // -> [1, 2, 3, 4]

[1, 2, [3, 4, [5, 6]]].flat();          // -> [1, 2, 3, 4, [5, 6]]

[1, 2, [3, 4, [5, 6]]].flat(2);         // -> [1, 2, 3, 4, 5, 6]

[1, 2, [3, 4, [5, 6]]].flat(Infinity);  // -> [1, 2, 3, 4, 5, 6]

let arr = [1, 2, [3, 4]];

console.log( arr.flat() );

arr =  [1, 2, [3, 4, [5, 6]]];

console.log( arr.flat() );
console.log( arr.flat(1) );
console.log( arr.flat(2) );
console.log( arr.flat(Infinity) );


3
এটি সুন্দর এবং ঝরঝরে তবে আমি মনে করি আপনি একটি ES6 ওভারডোজ করেছেন। বাহ্যিক ক্রিয়াটি তীর-ফাংশন হওয়ার দরকার নেই। আমি হ্রাস কলব্যাকের জন্য তীর-ফাংশনটির সাথে লেগে থাকব তবে চ্যাপ্টা নিজেই স্বাভাবিক ফাংশন হওয়া উচিত।
স্টিফেন সিম্পসন

3
@ স্টেফেনসিম্পসন কিন্তু বাইরের ফাংশনটি নন -অ্যারো-ফাংশন হওয়ার দরকার আছে কি? "চ্যাপ্টা নিজেই একটি সাধারণ ফাংশন হওয়া উচিত" - "সাধারণ" দ্বারা আপনি "নন-তীর" বলতে চান, তবে কেন? কেন কমাতে কলটিতে একটি তীর ফাংশন ব্যবহার করবেন? আপনি আপনার যুক্তি লাইন সরবরাহ করতে পারেন?
আপনাকে ধন্যবাদ

@ নোমিক আমার যুক্তিটি অযৌক্তিক। এটি মূলত স্টাইলের বিষয়; আমার মন্তব্যে আমার আরও পরিষ্কার হওয়া উচিত। এক বা অন্যটি ব্যবহার করার কোনও বড় কোডিং কারণ নেই। তবে ফাংশনটি তীরবিহীন হিসাবে দেখতে ও পড়া সহজ read অভ্যন্তরীণ ফাংশনটি তীর ফাংশন হিসাবে কার্যকর কারণ এটি আরও কমপ্যাক্ট (এবং কোনও প্রসঙ্গ অবশ্যই তৈরি হয়নি)। কমপ্যাক্ট পড়া সহজ ফাংশন তৈরি করতে এবং এই বিভ্রান্তি এড়াতে তীর ফাংশন দুর্দান্ত are যাইহোক, যখন এটি কোনও তীরবিহীন পর্যাপ্ত থাকে তখন এগুলি পড়তে আসলে আরও অসুবিধা করতে পারে। অন্যেরা যদিও মতানৈক্য হতে পারে!
স্টিফেন সিম্পসন 9

একটি RangeError: Maximum call stack size exceeded
ম্যাট ওয়েস্টলকে 14

@ ম্যাট, দয়া করে ত্রুটিটি পুনরুত্পাদন করার জন্য আপনি যে বিকাশ ব্যবহার করছেন তা ভাগ করুন
diziaq

27

একক উপাদান অ্যারের অ্যারে সমতল করার জন্য, আপনাকে একটি লাইব্রেরি আমদানি করার দরকার নেই, একটি সাধারণ লুপটি সহজ এবং সবচেয়ে কার্যকর সমাধান উভয়ই :

for (var i = 0; i < a.length; i++) {
  a[i] = a[i][0];
}

ডাউনভোটারদের কাছে: দয়া করে প্রশ্নটি পড়ুন, ডাউনভোট করবেন না কারণ এটি আপনার খুব আলাদা সমস্যার সাথে খাপ খায় না। এই সমাধানটি জিজ্ঞাসিত প্রশ্নের জন্য দ্রুত এবং সহজতম উভয়ই।


4
আমি বলব, "জিনিসগুলিকে আরও ক্রিপ্টিক খুঁজছেন না Don't" ^^

4
আমি বলতে চাই ... যখন আমি লোকেরা এর জন্য একটি লাইব্রেরি ব্যবহার করার পরামর্শ দিচ্ছি ... এটি পাগল ...
ডেনিস সাগুরেট

3
আহ, ঠিক এই জন্য একটি লাইব্রেরি ব্যবহার করা নিরীহ হবে ... তবে যদি এটি ইতিমধ্যে উপলব্ধ থাকে।

9
@dystroy লুপের শর্তযুক্ত অংশটি পড়ার মতো নয়। বা এটি কেবলমাত্র আমি: ডি
আন্দ্রেয়াস

4
এটি আসলে কতটা ক্রিপ্টিক তা বিবেচ্য নয়। এই কোডটি এটিকে "সমতল" ['foo', ['bar']]করে ['f', 'bar']
jonschlinkert

22
const common = arr.reduce((a, b) => [...a, ...b], [])

এইভাবে আমি আমার কোড জুড়ে এটি করি তবে আমি নিশ্চিত নই যে আপনার যদি খুব দীর্ঘ অ্যারে থাকে তবে গতি কীভাবে গ্রহণযোগ্য উত্তরের সাথে তুলনা করে
মাইকেল অ্যারন উইলসন

14

দয়া করে নোট করুন: যখন Function.prototype.apply( [].concat.apply([], arrays)) বা স্প্রেড অপারেটর ( [].concat(...arrays)) কোনও অ্যারের সমতল করার জন্য ব্যবহৃত হয়, উভয়ই বড় অ্যারেগুলির জন্য স্ট্যাক ওভারফ্লো করতে পারে, কারণ কোনও ফাংশনের প্রতিটি যুক্তি স্ট্যাকের উপরে সঞ্চিত থাকে।

এখানে কার্যক্ষম শৈলীতে একটি স্ট্যাক-নিরাপদ বাস্তবায়ন যা একে অপরের বিরুদ্ধে সবচেয়ে গুরুত্বপূর্ণ প্রয়োজনীয়তাগুলি ওজন করে:

  • পুনর্ব্যাবহার্যোগ্যতা
  • সুপাঠ্যতা
  • সংক্ষিপ্ত রুপ
  • কর্মক্ষমতা

// small, reusable auxiliary functions:

const foldl = f => acc => xs => xs.reduce(uncurry(f), acc); // aka reduce

const uncurry = f => (a, b) => f(a) (b);

const concat = xs => y => xs.concat(y);


// the actual function to flatten an array - a self-explanatory one-line:

const flatten = xs => foldl(concat) ([]) (xs);

// arbitrary array sizes (until the heap blows up :D)

const xs = [[1,2,3],[4,5,6],[7,8,9]];

console.log(flatten(xs));


// Deriving a recursive solution for deeply nested arrays is trivially now


// yet more small, reusable auxiliary functions:

const map = f => xs => xs.map(apply(f));

const apply = f => a => f(a);

const isArray = Array.isArray;


// the derived recursive function:

const flattenr = xs => flatten(map(x => isArray(x) ? flattenr(x) : x) (xs));

const ys = [1,[2,[3,[4,[5],6,],7],8],9];

console.log(flattenr(ys));

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


1
হা হা। আপনার উত্তরটি পুরোপুরি সম্মান করুন, যদিও এর মতো ক্রিয়ামূলক প্রোগ্রামিং পড়া এখনও আমার কাছে জাপানীজ চরিত্রটি পড়ার মতো (ইংরাজী স্পিকার)।
তরউইন স্ট্রোহ-স্পিজার

2
যদি আপনি নিজেকে একে একে ভাষার একমাত্র লক্ষ্য হিসাবে প্রকল্পের অংশ হিসাবে ভাষা বিতে ভাষার বৈশিষ্ট্যগুলি প্রয়োগ করে দেখতে পান তবে কোথাও কেউ ভুল ঘুরিয়ে নিয়েছে। এটা আপনি হতে পারে? শুধু সাথে যেতে const flatten = (arr) => arr.reduce((a, b) => a.concat(b), []);আপনাকে ভিজ্যুয়াল আবর্জনা এবং আপনার সতীর্থদের কাছে ব্যাখ্যা বাঁচাতে কেন আপনার আরও 3 টি অতিরিক্ত ফাংশন এবং কিছু ফাংশন কল প্রয়োজন।
দায়েরডেমান্ড

3
@ দায়েরডেমান্ড্ট তবে আপনি যদি এটি আলাদা ফাংশন হিসাবে লিখেন তবে সম্ভবত আপনি এগুলি অন্য কোডে পুনরায় ব্যবহার করতে সক্ষম হবেন।
মিশা পেরেকোস্কি

@ মাইকাপেরাকোভস্কি যদি আপনার কয়েকটি স্থানে এগুলি ব্যবহারের প্রয়োজন হয় তবে চাকাটি পুনরায় উদ্ভাবন করবেন না এবং এগুলি থেকে একটি প্যাকেজ চয়ন করবেন না - ডকুমেন্টেড এবং অন্যান্য ব্যক্তিদের দ্বারা সমর্থিত।
দেরডেম্যান্ড

12

ES6 ওয়ান লাইন ফ্ল্যাটেন

দেখুন lodash চেপ্টা , আন্ডারস্কোর চেপ্টা (অগভীর true)

function flatten(arr) {
  return arr.reduce((acc, e) => acc.concat(e), []);
}

অথবা

function flatten(arr) {
  return [].concat.apply([], arr);
}

দিয়ে পরীক্ষিত

test('already flatted', () => {
  expect(flatten([1, 2, 3, 4, 5])).toEqual([1, 2, 3, 4, 5]);
});

test('flats first level', () => {
  expect(flatten([1, [2, [3, [4]], 5]])).toEqual([1, 2, [3, [4]], 5]);
});

ES6 ওয়ান লাইন গভীর ফ্ল্যাটেন

ল্যাডাশ ফ্ল্যাটইনডিপ , আন্ডারস্কোর সমতল See

function flattenDeep(arr) {
  return arr.reduce((acc, e) => Array.isArray(e) ? acc.concat(flattenDeep(e)) : acc.concat(e), []);
}

দিয়ে পরীক্ষিত

test('already flatted', () => {
  expect(flattenDeep([1, 2, 3, 4, 5])).toEqual([1, 2, 3, 4, 5]);
});

test('flats', () => {
  expect(flattenDeep([1, [2, [3, [4]], 5]])).toEqual([1, 2, 3, 4, 5]);
});

আপনার ২ য় উদাহরণটি আরও ভাল লেখা হয়েছে Array.prototype.concat.apply([], arr)কারণ আপনি কেবলমাত্র concatফাংশনে যাওয়ার জন্য একটি অতিরিক্ত অ্যারে তৈরি করেছেন । রানটাইমগুলি যখন এটি চালায় তখন এটিকে অপ্টিমাইজ করতে পারে বা নাও করতে পারে, তবে প্রোটোটাইপটিতে ফাংশনটি অ্যাক্সেস করা কোনও অবস্থাতেই এর চেয়ে কোনও খারাপ লাগে না।
মারে

11

আপনি ব্যবহার করতে পারেন Array.flat()সঙ্গে Infinityনেস্টেড অ্যারের কোনো গভীরতা জন্য।

var arr = [ [1,2,3,4], [1,2,[1,2,3]], [1,2,3,4,5,[1,2,3,4,[1,2,3,4]]], [[1,2,3,4], [1,2,[1,2,3]], [1,2,3,4,5,[1,2,3,4,[1,2,3,4]]]] ];

let flatten = arr.flat(Infinity)

console.log(flatten)

ব্রাউজারের সামঞ্জস্যের জন্য এখানে চেক করুন


8

একটি হাস্কেলিস্কো পন্থা

function flatArray([x,...xs]){
  return x ? [...Array.isArray(x) ? flatArray(x) : [x], ...flatArray(xs)] : [];
}

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


1
@ অনুসারীদের সাথে একমত এই পুরো থ্রেডের মধ্যে সবচেয়ে মার্জিত সমাধানটি হ্যান্ডস করে।
নিকোলস ফ্যান্টোন

8

ES6 উপায়:

const flatten = arr => arr.reduce((acc, next) => acc.concat(Array.isArray(next) ? flatten(next) : next), [])

const a = [1, [2, [3, [4, [5]]]]]
console.log(flatten(a))

flattenএন-টাইমস নেস্টেড অ্যারেগুলির জন্য ES3 ফ্যালব্যাক সহ ফাংশনের জন্য ES5 উপায় :

var flatten = (function() {
  if (!!Array.prototype.reduce && !!Array.isArray) {
    return function(array) {
      return array.reduce(function(prev, next) {
        return prev.concat(Array.isArray(next) ? flatten(next) : next);
      }, []);
    };
  } else {
    return function(array) {
      var arr = [];
      var i = 0;
      var len = array.length;
      var target;

      for (; i < len; i++) {
        target = array[i];
        arr = arr.concat(
          (Object.prototype.toString.call(target) === '[object Array]') ? flatten(target) : target
        );
      }

      return arr;
    };
  }
}());

var a = [1, [2, [3, [4, [5]]]]];
console.log(flatten(a));


7

আপনার যদি কেবল 1 টি স্ট্রিং উপাদান সহ অ্যারে থাকে:

[["$6"], ["$12"], ["$25"], ["$25"]].join(',').split(',');

কাজ করবে বিটি যা আপনার কোড উদাহরণের সাথে বিশেষভাবে মেলে।


3
যে কে ভোট দিয়েছে, দয়া করে কেন তা ব্যাখ্যা করুন। আমি একটি শালীন সমাধান এবং আমি যে এটিকে সবচেয়ে পছন্দ করেছি তার সমাধানগুলির সন্ধান করছি।
বেনামে

2
@ অজ্ঞাতনামা আমি এটিকে নিচু করে দেখিনি যেহেতু এটি প্রযুক্তিগতভাবে প্রশ্নের প্রয়োজনীয়তা পূরণ করে, তবে এটি সম্ভবত কারণ এটি একটি দরিদ্র সমাধান যা সাধারণ ক্ষেত্রে কার্যকর নয়। এখানে আরও কতগুলি ভাল সমাধান রয়েছে তা বিবেচনা করে, আমি কখনই কাউকে এইটির সাথে যাওয়ার পরামর্শ দিই না কারণ এটি আপনার একাধিক উপাদানগুলির মুহুর্তগুলিকে ভেঙে দেয় বা যখন তারা স্ট্রিং না করে।
Thor84no

2
আমি এই সমাধানটি পছন্দ করি =)
হুয়ে টান

2
এটি 1 টি স্ট্রিং উপাদানের সাথে কেবল অ্যারেগুলি পরিচালনা করে না, এটি এই অ্যারেটিও পরিচালনা করে ['$4', ["$6"], ["$12"], ["$25"], ["$25", "$33", ['$45']]].join(',').split(',')

আমি নিজেই এই পদ্ধতিটি আবিষ্কার করেছি, তবে জানতাম এটি ইতিমধ্যে কোথাও নথিভুক্ত থাকতে হবে, আমার অনুসন্ধান এখানেই শেষ হয়েছে। এই সমাধানটির অপূর্ণতা হ'ল, এটি সংখ্যাগুলিকে, বুলিয়ানগুলিকে স্ট্রিংয়ে জড়ো করে, চেষ্টা করে [1,4, [45, 't', ['e3', 6]]].toString().split(',') ---- বা ----- [1,4, [45, 't', ['e3', 6], false]].toString().split(',')
সুধনসু চৌধারি

7
var arrays = [["a"], ["b", "c"]];
Array.prototype.concat.apply([], arrays);

// gives ["a", "b", "c"]

(আমি এটি @ উত্তরহ্বিয়ারের মন্তব্যের ভিত্তিতে পৃথক উত্তর হিসাবে লিখছি।)


7

আমি একটি স্থান দক্ষ জেনারেটর ফাংশন সুপারিশ :

function* flatten(arr) {
  if (!Array.isArray(arr)) yield arr;
  else for (let el of arr) yield* flatten(el);
}

// Example:
console.log(...flatten([1,[2,[3,[4]]]])); // 1 2 3 4

যদি ইচ্ছা হয় তবে নীচের মত সমতল মানগুলির একটি অ্যারে তৈরি করুন:

let flattened = [...flatten([1,[2,[3,[4]]]])]; // [1, 2, 3, 4]

আমি এই পদ্ধতির পছন্দ। অনুরূপ stackoverflow.com/a/35073573/1175496 কিন্তু বিস্তার অপারেটর ব্যবহার ...জেনারেটরের মাধ্যমে পুনরুক্তি করতে।
লাল মটর 14

6

আমি বরং পুরো অ্যারেটিকে যেমন স্ট্রিংয়ে রূপান্তরিত করব তবে অন্য উত্তরগুলির মতো নয় যে পদ্ধতিটি JSON.stringifyব্যবহার করে এবং ব্যবহার না করে toString()যা অনাকাঙ্ক্ষিত ফলাফল দেয়।

এই JSON.stringifyআউটপুটটির সাথে, বাকি সমস্তটি হ'ল সমস্ত বন্ধনী অপসারণ করা, আরম্ভ এবং শেষ বন্ধনীগুলি দিয়ে ফলাফলটি আবার গুটিয়ে রাখা এবং ফলাফলটি পরিবেশন করা হয় JSON.parseযার সাহায্যে স্ট্রিংটিকে "জীবন" এ ফিরিয়ে আনে।

  • কোনও গতি ব্যতীত অসীম নেস্টেড অ্যারে পরিচালনা করতে পারে।
  • ঠিকমতো অ্যারে আইটেমগুলি পরিচালনা করতে পারে যা কমাযুক্ত স্ট্রিং রয়েছে।

var arr = ["abc",[[[6]]],["3,4"],"2"];

var s = "[" + JSON.stringify(arr).replace(/\[|]/g,'') +"]";
var flattened = JSON.parse(s);

console.log(flattened)

  • কেবল স্ট্রিং / সংখ্যাগুলির বহুমাত্রিক অ্যারে (অবজেক্ট নয়)

আপনার সমাধানটি ভুল। ["345", "2", "3,4", "2"]
এটিতে

@ রিলিজ্যানপ - আপনি সেই অ্যারে আইটেমটির মানটি ভুল বুঝেছেন। আমি ইচ্ছাকৃতভাবে সেই কমাটিকে একটি মান হিসাবে রেখেছি এবং অ্যারে ডিলিমিটার কমা হিসাবে নয় অন্য সকলের থেকে আমার সমাধানের শক্তিকে জোর দেওয়ার জন্য, যা আউটপুট হবে "3,4"
vsync

1
আমি ভুল
বুঝেছি

এটি অবশ্যই আমি এর জন্য দ্রুততম সমাধানটি দেখেছি বলে মনে হয়; @vsync- এর কোনও অসুবিধাগুলি সম্পর্কে আপনি কি অবগত আছেন (বাস্তবে এটি খানিকটা হ্যাকি মনে হচ্ছে - নেস্টেড অ্যারেগুলিকে স্ট্রিং হিসাবে বিবেচনা করে: ডি)
জর্জ ক্যাটসানোস ২

@ জর্জক্যাটসানোস - এই পদ্ধতিটি অ্যারে আইটেমগুলির (এবং নেস্টেড আইটেমগুলির জন্য) কাজ করবে না যা আদিম মূল্য নয়, উদাহরণস্বরূপ এমন একটি আইটেম যা কোনও ডোম উপাদানকে নির্দেশ করে
ভাইসেক ২

6

আপনি নতুন Array.Flat()পদ্ধতিটিও দেখতে পারেন । এটি নিম্নলিখিত পদ্ধতিতে কাজ করে:

let arr = [["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"]].flat()

console.log(arr);

flat()পদ্ধতি তা গভীরতা 1 স্তরে যাও recursively আপ ঘনিভূত সমস্ত উপ-অ্যারে উপাদানের সঙ্গে একটি নতুন অ্যারে তৈরি করে (অ্যারে ভিতরে অর্থাত অ্যারে)

আপনি যদি 3 টি মাত্রিক বা এমনকি উচ্চতর মাত্রিক অ্যারেগুলি সমতল করতে চান তবে আপনি কেবল ফ্ল্যাট পদ্ধতিতে একাধিকবার কল করেন। উদাহরণস্বরূপ (3 মাত্রা):

let arr = [1,2,[3,4,[5,6]]].flat().flat().flat();

console.log(arr);

সাবধান হও!

Array.Flat()পদ্ধতি তুলনামূলকভাবে নতুন। যেমন পুরানো ব্রাউজারগুলি সম্ভবত পদ্ধতিটি প্রয়োগ করে না। আপনি যদি সমস্ত ব্রাউজারে কাজ করার কোড চান তবে আপনার জেএসকে পুরানো সংস্করণে স্থানান্তর করতে হতে পারে। বর্তমান ব্রাউজারের সামঞ্জস্যের জন্য এমডি ওয়েব ডক্সের জন্য পরীক্ষা করুন।


2
উচ্চ মাত্রিক অ্যারে ফ্ল্যাট করতে আপনি কেবল Infinityযুক্তি দিয়ে ফ্ল্যাট পদ্ধতিতে কল করতে পারেন । arr.flat(Infinity)
মিখাইল

এটা খুব সুন্দর সংযোজন, ধন্যবাদ মিখাইল!
উইলেম ভ্যান ডার ভীন


5

এটি কঠিন নয়, কেবল অ্যারেগুলিতে পুনরাবৃত্তি করুন এবং সেগুলি মার্জ করুন:

var result = [], input = [["$6"], ["$12"], ["$25"], ["$25"], ["$18"]];

for (var i = 0; i < input.length; ++i) {
    result = result.concat(input[i]);
}

5

দেখে মনে হচ্ছে এটি দেখার মতো একটি কাজের মতো!

  • নীড়ের একাধিক স্তর পরিচালনা করে
  • খালি অ্যারে এবং অ অ্যারে প্যারামিটারগুলি পরিচালনা করে
  • কোনও রূপান্তর নেই
  • আধুনিক ব্রাউজার বৈশিষ্ট্যগুলির উপর নির্ভর করে না

কোড:

var flatten = function(toFlatten) {
  var isArray = Object.prototype.toString.call(toFlatten) === '[object Array]';

  if (isArray && toFlatten.length > 0) {
    var head = toFlatten[0];
    var tail = toFlatten.slice(1);

    return flatten(head).concat(flatten(tail));
  } else {
    return [].concat(toFlatten);
  }
};

ব্যবহার:

flatten([1,[2,3],4,[[5,6],7]]);
// Result: [1, 2, 3, 4, 5, 6, 7] 

সাবধান, flatten(new Array(15000).fill([1]))নিক্ষেপ Uncaught RangeError: Maximum call stack size exceededএবং 10 সেকেন্ডের জন্য আমার devTools
হিমায়িত

@ পিট্রোভিস্মার, আমার পরীক্ষা প্রায় 1s এর কাছাকাছি।
ইভান ইয়ান

5

আমি এটি পুনরাবৃত্তি এবং ক্লোজারগুলি ব্যবহার করে করেছি

function flatten(arr) {

  var temp = [];

  function recursiveFlatten(arr) { 
    for(var i = 0; i < arr.length; i++) {
      if(Array.isArray(arr[i])) {
        recursiveFlatten(arr[i]);
      } else {
        temp.push(arr[i]);
      }
    }
  }
  recursiveFlatten(arr);
  return temp;
}

1
সহজ এবং মিষ্টি, এই উত্তর গৃহীত উত্তরের চেয়ে ভাল কাজ করে। এটি কেবল প্রথম স্তরের নয়, গভীরভাবে নেস্টেড স্তরে ফ্ল্যাট করে
ওম শঙ্কর


@ ড্যাশাম্বলস সঠিক - পার্থক্যটি হ'ল এটি যদি বন্ধ হয়ে যায় তবে আপনি অভ্যন্তরীণ ফাংশনটি বাইরের দিকে ফিরিয়ে আনতেন এবং যখন বাহ্যিক ফাংশন শেষ হয় আপনি তার অভ্যন্তরে অ্যাক্সেসের জন্য অভ্যন্তরীণ ফাংশনটি ব্যবহার করতে পারেন। এখানে বাহ্যিক ক্রিয়াকলাপের আজীবন অভ্যন্তরীণ ফাংশনের চেয়ে দীর্ঘ হয় তাই "ক্লোজার" কখনই তৈরি হয় না।
মারে

5

আমি অন্য দিন ইএস 6 জেনারেটরের সাথে বোকা বানাচ্ছিলাম এবং এই টুকরোটি লিখেছিলাম । যেটা বহন করে...

function flatten(arrayOfArrays=[]){
  function* flatgen() {
    for( let item of arrayOfArrays ) {
      if ( Array.isArray( item )) {
        yield* flatten(item)
      } else {
        yield item
      }
    }
  }

  return [...flatgen()];
}

var flatArray = flatten([[1, [4]],[2],[3]]);
console.log(flatArray);

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

আমি এর পারফরম্যান্স পরীক্ষা করিনি, তবে আমি জেনারেটর এবং ফলন * অপারেটর ব্যবহারের একটি দুর্দান্ত সাধারণ উদাহরণ বলে মনে করি।

তবে আবার, আমি ঠিক বোকা বানাচ্ছিলাম তাই আমি নিশ্চিত যে এটি করার আরও আরও কার্যকরী উপায় রয়েছে।


1
অনুরূপ উত্তর (জেনারেটর এবং ফলন প্রতিনিধি ব্যবহার করে), তবে পিএইচপি ফর্ম্যাটে
দ্য রেড মটর

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