এইচটিএমএল কালেকশনকে একটি অ্যারেতে রূপান্তর করার সর্বাধিক দক্ষ উপায়


391

এইচটিএমএল কালেকশনকে অ্যারেতে রূপান্তর করার আরও কার্যকর উপায় কি বলা হয়েছে, সংগ্রহের বিষয়বস্তুগুলির মাধ্যমে পুনরুক্তি করা এবং ম্যানুয়ালি প্রতিটি আইটেমকে অ্যারে রূপান্তর করা ছাড়া?


10
"দক্ষ" বলতে কী বোঝায়? তাহলে সেরা পারফর্মিং, একটি জন্য লুপ সাধারণত দ্রুত চেয়ে Array.prototype.slice । একটি লুপ এছাড়াও ব্রাউজার (অর্থাত সব) একটি ব্যাপকতর বিভিন্ন কাজ করে, তাই ঐ মানদণ্ড দ্বারা এটি করা হয় "সবচেয়ে কার্যকর উপায়"। এবং এটি খুব সামান্য কোড: for (var a=[], i=collection.length; i;) a[--i] = collection[i];তাই সেখানে "কন" তেমন কিছু নয় :-)
রবজি

@ রবজি আপনাকে ধন্যবাদ - আমি যদি + পারতাম তবে আমি 59 ডলার দেব! ;-)
স্ল্যাশব্যাক

1
এ খুঁজছি বর্তমান ব্রাউজার কর্মক্ষমতা , ফালি বেশিরভাগই আপ loops সঙ্গে কর্মক্ষমতা নিরিখে ধরা হয়েছে Chrome এ ছাড়া। বিপুল সংখ্যক উপাদান এবং লুপের সামান্য অপ্টিমাইজেশন ব্যবহার করে ফলাফলগুলি প্রায় একই রকম হয় , ক্রোম বাদে যেখানে একটি লুপ খুব দ্রুত।
রবজি

আমি একটি জেএসপিআইপি পরীক্ষা তৈরি করেছি যা উভয় পদ্ধতিতে দেখায় যা @harpo উল্লিখিত পাশাপাশি পারফরম্যান্সের জন্য jquery পরীক্ষা করে। আমি খুঁজে পেয়েছি যে jquery উভয় জাভাস্ক্রিপ্ট পদ্ধতির তুলনায় কিছুটা ধীর এবং উচ্চ পারফরম্যান্স জেএস পরীক্ষার ক্ষেত্রে পরিবর্তিত হয়। Chrome 59.0.3071 / ম্যাক ওএস এক্স 10.12.5 ব্যবহার পছন্দ করে Array.prototype.slice.callএবং সাহসী (ক্রোম 59.0.3071 এর উপর ভিত্তি করে) একাধিক রান নিয়ে দুটি জাভাস্ক্রিপ্ট পরীক্ষার মধ্যে কার্যত কোনও পার্থক্য নেই। Jsperf.com/htmlcollection-array-vs-jquery-children
নিউক্লিয়ারপিয়ন

jsben.ch/h2IFA => এটি করার সর্বাধিক সাধারণ পদ্ধতির জন্য পারফরম্যান্স পরীক্ষা
এসপ্রেটনেটস্কেপ

উত্তর:


696
var arr = Array.prototype.slice.call( htmlCollection )

"নেটিভ" কোড ব্যবহার করে একই প্রভাব ফেলবে।

সম্পাদন করা

যেহেতু এটি প্রচুর মতামত পেয়েছে, নোট করুন (@ অরিওলের মন্তব্য অনুসারে) যে নিম্নলিখিত আরও সংক্ষিপ্ত প্রকাশটি কার্যকরভাবে সমতুল্য:

var arr = [].slice.call(htmlCollection);

তবে @ জুসিআর'র মন্তব্যে নোট করুন, "ভার্বোস" ফর্মের বিপরীতে এটি প্রক্রিয়াটিতে একটি খালি, অব্যবহৃত এবং সত্যই অব্যর্থ্য অ্যারের উদাহরণ তৈরি করে। সংকলকগণ এটি সম্পর্কে যা করেন তা প্রোগ্রামারের কেনের বাইরে।

সম্পাদন করা

ECMAScript 2015 (ES 6) যেহেতু অ্যারে.ফর্ম থেকে রয়েছে :

var arr = Array.from(htmlCollection);

সম্পাদন করা

ECMAScript 2015 এছাড়াও স্প্রেড অপারেটর সরবরাহ করে , যা কার্যত সমান Array.from(যদিও নোটটি Array.fromম্যাপিং ফাংশনটিকে দ্বিতীয় তর্ক হিসাবে সমর্থন করে)।

var arr = [...htmlCollection];

আমি নিশ্চিত করেছি যে উপরের দু'টিই কাজ করছে NodeList

উল্লিখিত পদ্ধতিগুলির জন্য একটি পারফরম্যান্স তুলনা: http://jsben.ch/h2IFA


7
এটি আই 6 এ ব্যর্থ।
বর্ডারগুলি

29
শর্টকাটও [].slice.call(htmlCollection)কাজ করে।
ওরিওল

1
@ ক্রিসনিয়েলসন হ্যাঁ আমি এতে ভুল তথ্য ছিল। চারপাশে ছড়িয়ে দেওয়ার জন্য দুঃখিত। আমি বুঝতে পারি না যে আমি এখানে এখানেও বলেছি। বিভ্রান্তি এড়ানোর জন্য মন্তব্যটি মুছে ফেলা হয়েছে তবে প্রসঙ্গের জন্য আমি কোথাও পড়েছি (বা ভুল অনুবাদ করেছি) যে কোনও এইচটিএমএল কালেকশনকে টুকরো টুকরো করে ফেললে তা অ্যারে এবং সংগ্রহের মতোই আচরণ করতে পারে। সম্পূর্ণ ভুল।
এরিক রেপেন

3
[] .স্লাইস শর্টকাট সমতুল্য নয় কারণ এটি অব্যবহৃত ফাঁকা অ্যারের উদাহরণ তৈরি করে। যদিও কম্পাইলাররা এটি অপ্টিমাইজ করতে সক্ষম কিনা তা নিশ্চিত নয়।
JussiR

3
Array.fromযেমন from, আইই ১১ সমর্থন করে না।
ফ্রাঙ্ক কনিজন

86

এটি সবচেয়ে দক্ষ কিনা তা নিশ্চিত নন, তবে একটি সংক্ষিপ্ত ES6 সিনট্যাক্স হতে পারে:

let arry = [...htmlCollection] 

সম্পাদনা করুন: ক্রিস_এফ মন্তব্য থেকে অন্য একটি:

let arry = Array.from(htmlCollection)

9
অতিরিক্তভাবে, ES6 যোগ করেছেArray.from()
Chris_F

4
প্রথমটির দিকে নজর রাখুন, যখন বাবেলের সাথে স্থানান্তরিত হচ্ছে তখন একটি সূক্ষ্ম বাগ রয়েছে যেখানে [... এইচটিএমএল সংগ্রহ] কেবলমাত্র উপাদান হিসাবে এটি এইচটিএমএল সংগ্রহের সাথে একটি অ্যারের ফিরিয়ে দেবে।
মার্সেল এম

3
অ্যারে স্প্রেড অপারেটর এইচটিএমএল সংগ্রহের কাজ করে না। এটি কেবল নোডলিস্টের জন্য প্রযোজ্য।
ববি

1
Array.fromযেমন from, আইই ১১ সমর্থন করে না।
ফ্রাঙ্ক কনিজন

বেঞ্চমার্ক বিস্তার অপারেটর মত দেখায় এই 2. দ্রুত বাইরে
RedSparr0w

20

আমি Array.prototypeসাধারণভাবে পদ্ধতিগুলি পাওয়ার আরও সংক্ষিপ্ত পদ্ধতিটি দেখেছি যা ঠিক পাশাপাশি কাজ করে। একটি HTMLCollectionবস্তুকে একটিতে রূপান্তর করাArray নীচে প্রদর্শিত হয়:

[] .স্লাইস.call (আপনার এইচটিএমএল সংকলন অবজেক্ট);

এবং, মন্তব্যগুলিতে যেমন বলা হয়েছে, পুরানো ব্রাউজারগুলির যেমন আই and এবং তার আগে এর জন্য আপনাকে কেবল একটি সামঞ্জস্য ফাংশন ব্যবহার করতে হবে, যেমন:

function toArray(x) {
    for(var i = 0, a = []; i < x.length; i++)
        a.push(x[i]);

    return a
}

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


6

একটি ক্রস ব্রাউজার বাস্তবায়নের জন্য আমি প্রোটোটাইপ.জেএস $A ফাংশনটি দেখি

1.6.1 থেকে অনুলিপি :

function $A(iterable) {
  if (!iterable) return [];
  if ('toArray' in Object(iterable)) return iterable.toArray();
  var length = iterable.length || 0, results = new Array(length);
  while (length--) results[length] = iterable[length];
  return results;
}

এটি Array.prototype.sliceসম্ভবত ব্যবহার করে না কারণ এটি প্রতিটি ব্রাউজারে উপলব্ধ নয়। আমি ভয় পাচ্ছি যে পারফরম্যান্সটি খুব খারাপ, কারণ পতনের পিছনে একটি জাভাস্ক্রিপ্ট লুপ রয়েছে iterable


2
ওপিতে "উক্ত সংগ্রহের বিষয়বস্তুগুলির মধ্য দিয়ে পুনরুক্তি করা এবং প্রতিটি আইটেমকে ম্যানুয়ালি অ্যারেতে ঠেলে দেওয়া" ছাড়া অন্য কোনও উপায়ের জন্য জিজ্ঞাসা করা হয়েছিল, তবে এটি $Aবেশিরভাগ সময় কার্যকারিতাটি করে।
Luc125

1
আমার মনে হয় আমি যে পয়েন্টটি তৈরির চেষ্টা করছিলাম সেটি হ'ল এটি করার কোনও ভাল উপায় নেই, প্রোটোটাইপ.জেএস কোডটি দেখায় যে আপনি 'টু অ্যারে' পদ্ধতির সন্ধান করতে পারেন তবে সেই পুনরাবৃত্তিটি নিরাপদতম পথে ব্যর্থ করে
গ্যারেথ ডেভিস

1
এটি বিরল অ্যারেগুলিতে নতুন, অপরিজ্ঞাত সদস্য তৈরি করবে। অ্যাসাইনমেন্টের আগে একটি হাইওনপ্রপার্টি পরীক্ষা করা উচিত ।
রবজি 4'16

3

এটি আমার ব্যক্তিগত সমাধান, এখানে তথ্যের ভিত্তিতে (এই থ্রেড):

var Divs = new Array();    
var Elemns = document.getElementsByClassName("divisao");
    try {
        Divs = Elemns.prototype.slice.call(Elemns);
    } catch(e) {
        Divs = $A(Elemns);
    }

যেখানে post এ গ্যারেথ ডেভিস তার পোস্টে বর্ণনা করেছেন:

function $A(iterable) {
  if (!iterable) return [];
  if ('toArray' in Object(iterable)) return iterable.toArray();
  var length = iterable.length || 0, results = new Array(length);
  while (length--) results[length] = iterable[length];
  return results;
}

যদি ব্রাউজার সেরা উপায়ে সমর্থন করে, ঠিক আছে, অন্যথায় ক্রস ব্রাউজারটি ব্যবহার করবে।


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

2
গ্যারেথ ডেভিস এর উত্তরের সাথে সাথে এটি স্পার্স অ্যারেগুলিতে নতুন, অপরিজ্ঞাত সদস্য তৈরি করে, তাই [,,]হয়ে যায় [undefined, undefined]
রবজি 4'16

আমি এখনও এই ধরণের ঝামেলা পাইনি। এটি 3 টি উপাদান সংগ্রহের ফলাফলকে 2 টি উপাদান সহ একটি অ্যারের ফলাফল দেয়। খালি অপরিজ্ঞাত হয়ে ওঠার জন্য, এটি জাভাস্ক্রিপ্টের সীমাবদ্ধতার একটি বিট, আমি জিএসস আপনি অনির্ধারিত পরিবর্তে নাল প্রত্যাশা করছেন, তাই না?
গুস্তাভো

3

এটি পূর্ববর্তী আই সংস্করণ সহ সমস্ত ব্রাউজারে কাজ করে।

var arr = [];
[].push.apply(arr, htmlCollection);

যেহেতু এই মুহুর্তে jsperf এখনও নিচে রয়েছে তাই এখানে একটি জেসফিল ​​রয়েছে যা বিভিন্ন পদ্ধতির পারফরম্যান্সের সাথে তুলনা করে। https://jsfiddle.net/qw9qf48j/


চেষ্টা করুনvar args = (htmlCollection.length === 1 ? [htmlCollection[0]] : Array.apply(null, htmlCollection));
শাহর শোকরানী

3

দক্ষ পদ্ধতিতে অ্যারের মতো অ্যারে রূপান্তর করতে আমরা jQuery ব্যবহার করতে পারি makeArray:

MakeArray: একটি অ্যারের মতো অবজেক্টটিকে সত্য জাভাস্ক্রিপ্ট অ্যারে রূপান্তর করুন।

ব্যবহার:

var domArray = jQuery.makeArray(htmlCollection);

একটু অতিরিক্ত:

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

var domDataLength = domData.length //Better performance, no need to calculate every iteration the domArray length
var resultArray = new Array(domDataLength) // Since we know the length its improves the performance to declare the result array from the beginning.

for (var i = 0 ; i < domDataLength ; i++) {
    resultArray[i] = domArray[i]; //Since we already declared the resultArray we can not make use of the more expensive push method.
}

অ্যারের মত কি?

এইচটিএমএল কালেকশন একটি "array-like"অবজেক্ট, অ্যারের মতো অবজেক্টগুলি অ্যারের অবজেক্টের মতো তবে এর কার্যকারিতা সংজ্ঞাটি অনেকটা অনুপস্থিত:

অ্যারের মতো অবজেক্টগুলি অ্যারের মতো দেখায়। তাদের বিভিন্ন সংখ্যাযুক্ত উপাদান এবং একটি দৈর্ঘ্যের সম্পত্তি রয়েছে। কিন্তু সেখানেই মিল থামে। অ্যারের মতো অবজেক্টগুলির অ্যারের কোনও ফাংশন নেই এবং ইন-লুপগুলি এমনকি কাজ করে না!

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