কিছু পুনরাবৃত্তিযোগ্য কিনা তা পরীক্ষা করা হচ্ছে


104

এমডিএন ডক্সে: https://developer.mozilla.org/en-US/docs/Web/ জাভা স্ক্রিপ্ট / রেফারেন্স / স্ট্যাটমেন্টস / for...of

for...ofকনস্ট্রাক্ট "iterable" বস্তু পুনরুক্তি পাবে বর্ণনা করা হয়েছে। কিন্তু কোনও বস্তু পুনরাবৃত্তিযোগ্য কিনা তা স্থির করার কোনও ভাল উপায় আছে?

আমি অ্যারে, পুনরাবৃত্তকারী এবং জেনারেটরগুলির জন্য সাধারণ সম্পত্তিগুলি সন্ধান করার চেষ্টা করেছি, তবে তা করতে অক্ষম হয়েছি।

for ... ofএকটি চেষ্টা ব্লক করার চেষ্টা এবং ধরণের ত্রুটিগুলি যাচাই করার পাশাপাশি , এটি করার কোনও পরিষ্কার উপায় আছে কি?


অবশ্যই, লেখক হিসাবে, আপনি কি জানেন যে আপনার বস্তুটি পুনরাবৃত্তিযোগ্য?
অ্যান্ড্রুব

5
বস্তুটি আর্গুমেন্ট হিসাবে পাস করা হয়েছে, আমি নিশ্চিত না।
সিমোনজ্যাক

1
যুক্তির ধরণটি কেন পরীক্ষা করা হচ্ছে না?
জেমস ব্রুকনার

2
@ অ্যান্ড্রু-বুচান, জেমস ব্রুকনার: প্রকারের জন্য পরীক্ষা করা কার্যকর হতে পারে তবে আপনি যদি এমডিএন ডক্সটি পড়েন তবে আপনি লক্ষ্য করবেন যে এটি "অ্যারের মতো" বলেছে। আমি জানি না এর অর্থ কী, ঠিক তাই, এই প্রশ্নটি।
সাইমনজ্যাক

1
wiki.ecmascript.org/doku.php?id=harmony:iterators " একটি বস্তু যদি এর কোনও iterator()পদ্ধতি থাকে তবে তা পুনরাবৃত্তিযোগ্য । " তবুও, যেহেতু এটি একটি খসড়া তাই কেবল একটি চেক প্রয়োগ-নির্ভর dependent আপনি কোন পরিবেশ ব্যবহার করেন?
বার্গি

উত্তর:


142

পুনরুক্তিযোগ্যতা যাচাইয়ের সঠিক উপায়টি নিম্নরূপ:

function isIterable(obj) {
  // checks for null and undefined
  if (obj == null) {
    return false;
  }
  return typeof obj[Symbol.iterator] === 'function';
}

এটি কেন কাজ করে (গভীরতার সাথে পুনরাবৃত্ত প্রোটোকল): https://developer.mozilla.org/en/docs/Web/ জাভা স্ক্রিপ্ট / রেফারেন্স / ইন্টেরেশন_প্রোটোকল

যেহেতু আমরা..এর জন্য কথা বলছি, আমি ধরে নিই, আমরা ইএস 6 মানসিকতায় আছি।

এছাড়াও, অবাক হবেন না যে এই ফাংশনটি trueযদি objএকটি স্ট্রিং হয় তবে স্ট্রিংগুলি তাদের চরিত্রগুলি দিয়ে পুনরাবৃত্তি করে।


14
বা Symbol.iterator in Object(obj),।

14
'ইন' অপারেটরটি ব্যবহার করার ক্ষেত্রে (কমপক্ষে) একটি ব্যতিক্রম রয়েছে: স্ট্রিং। স্ট্রিং পুনরাবৃত্ত হয় (for..of এর নিরিখে) তবে আপনি এটিতে 'ইন' ব্যবহার করতে পারবেন না। যদি এটির জন্য না হয় তবে আমি 'ইন' ব্যবহার করতে পছন্দ করব এটি অবশ্যই সুন্দর লাগবে।
টমাস কুলিচ

এটা করা উচিত নয় return typeof obj[Symbol.iterator] === 'function'? "পুনরাবৃত্তিযোগ্য হওয়ার জন্য, কোনও অবজেক্টকে অবশ্যই @@ পুনরুক্তি পদ্ধতিটি প্রয়োগ করতে হবে" - এটি পদ্ধতিটি নির্দিষ্ট করে
কলম

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

typeof Object(obj)[Symbol.iterator] === 'function'সব ক্ষেত্রে কাজ করবে ?
ক্রেগ গিডনি

26

কেন এত ভার্বোস?

const isIterable = object =>
  object != null && typeof object[Symbol.iterator] === 'function'

56
Readability > Clevernessসর্বদা ফিরে আসে true
jfmercer

26
হাহা, সাধারণত আমি অপঠনযোগ্য কোড সম্পর্কে অভিযোগ করার একাই, তবে আসলে আমি মনে করি এটি বেশ পঠনযোগ্য। একটি ইংরেজী বাক্যাংশের মতো: যদি বস্তুটি শূন্য না হয় এবং প্রতীকী পুনরাবৃত্ত সম্পত্তি কোনও ফাংশন হয়, তবে এটি পুনরাবৃত্তিযোগ্য। যদি এটি মরে যাওয়া সহজ না হয় তবে আমি জানি না ...
অ্যাডিয়াস

4
ইমো, "পাঠযোগ্যতা" এর বিন্দুটি আসল পড়া ছাড়া কী হচ্ছে তা বোঝা
দিমিত্রি পার্জিটস্কি

2
@ আলেকজান্ডার মিলস আপনার উন্নতি কোডটি আরও খারাপ করেছে। 1. ভালো লেগেছে @jfmercer বলেন Readability > Cleverness, তাই পরিবর্তনশীল সংক্ষেপিত objectকরার oকেউ কিছু করতে সাহায্য করে। 2. একটি খালি স্ট্রিং ''পুনরাবৃত্ত এবং তাই এটি অবশ্যই ফিরে আসবে true
অ্যাডিয়াস

1
বুঝেছি, আমি বুঝতে পেরেছিলাম যে এটি ব্যবহার করার কোনও কারণ ছিল!= null
আলেকজান্ডার মিলস

22

সহজ সমাধানটি আসলে এটি:

function isIterable (value) {
  return Symbol.iterator in Object(value);
}

Objectএমন কোনও জিনিস মুড়ে ফেলবে যা একটিতে কোনও অবজেক্ট নয়, inঅপারেটরটিকে মূল মান কোনও অবজেক্ট না হলেও কাজ করতে দেয় । nullএবং undefinedখালি বস্তুতে পরিণত হয় যাতে এজ কেস সনাক্তকরণের প্রয়োজন হয় না এবং স্ট্রিং অবজেক্টগুলিতে স্ট্রিংগুলি আবৃত হয় যা পুনরাবৃত্তিযোগ্য।


1
আপনি ভুল প্রতীক ব্যবহার করেছেন। এটা: Symbol.iterator
গিল

@ গিল আপনি একদম ঠিক আছেন, উফ! আমার সরাসরি পোষ্টে টাইপ করার পরিবর্তে অনুলিপিযুক্ত পরীক্ষিত কোড থাকা উচিত।
ডোমিনো

এই Objectজাতীয় চেকের জন্য একটি নতুন অবজেক্টের সৃষ্টি ব্যর্থ।
রুবেন ভার্বার্গ

আমি বলতে পারি না ঠিক কীভাবে Objectফাংশনটি বাস্তবায়িত হয় তা আমি জানি তবে এটি কেবলমাত্র একটি নতুন অবজেক্ট তৈরি করে যদি valueইতিমধ্যে কোনও বস্তু না হয়। আমি সমন্বয় আশা করতে চাই inএবং Object(...)সহজে অপ্টিমাইজ করতে পারেন কিছু ব্রাউজার ইঞ্জিন হতে, বলে অসদৃশ value !== undefined && value !== null && value[Symbol.iterator] && true। এছাড়াও, এটি অত্যন্ত পঠনযোগ্য, যা আমি যত্নশীল।
ডোমিনো

9

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

বিষয়গুলিকে পরিষ্কার করার জন্য উপরের সমস্ত উদাহরণ falseএই বস্তুর উপর ফিরে {a: 1, b: 2}আসে কারণ সেই বস্তুটি পুনরাবৃত্তি প্রোটোকলটি কার্যকর করে না। সুতরাং আপনি এটি দিয়ে একটি পুনরায় for...of বিট করতে সক্ষম হবেন না তবে আপনি এখনও এটি দিয়ে পারেন for...in

সুতরাং আপনি যদি বেদনাদায়ক ভুলগুলি এড়াতে চান তবে নীচের মতো আপনার পদ্ধতিটির নাম পরিবর্তন করে আপনার কোডটিকে আরও নির্দিষ্ট করে তুলুন:

/**
 * @param variable
 * @returns {boolean}
 */
const hasIterationProtocol = variable =>
    variable !== null && Symbol.iterator in Object(variable);

আপনি কোন বোধগম্য হয় না। কেন মনে হয় এটি ভেঙে যাবে undefined?
অ্যাডিয়াস

@ এডিয়াস আমার ধারণা আমি ভুলভাবে ধরে নিয়েছি যে object !== nullআপনি নিজের জবাব দিচ্ছেন কিন্তু আপনি এমনটি করছেন object != nullযে এটি undefinedনির্দিষ্ট ক্ষেত্রে ভেঙে যাচ্ছে না । আমি আমার উত্তর অনুসারে আপডেট করেছি।
ফ্রান্সেসকো ক্যাসুলা

আচ্ছা আমি দেখি. বিটিডব্লিউ: আপনার কোডটি ভুল। hasIterationProtocol('')ফিরতে হবে true! আপনি কীভাবে আপনার কোডটি সরিয়ে ফেলেন এবং কেবল পুনরাবৃত্তযোগ্য ব্যাখ্যা বিভাগটি ছেড়ে যান, এটিই হ'ল যা আপনার উত্তরে আসল মান / নতুন কিছু যুক্ত করে।
অ্যাডিয়াস

1
এটি trueপুরানো উত্তরের কিছু অংশ সরিয়ে আমি ফাংশন দুটি একত্রিত করে দিয়েছিলাম এবং কঠোর তুলনাটি ভুলে গিয়েছিলাম। এখন আমি আসল উত্তরটি পিছনে রেখেছি যা ভাল কাজ করছিল।
ফ্রান্সেসকো ক্যাসুলা

1
আমি কখনই ব্যবহার করার কথা ভাবতাম না Object(...), দুর্দান্ত ধরা catch তবে সেক্ষেত্রে নাল চেকের দরকার নেই।
ডোমিনো

2

আজকাল, যেমন ইতিমধ্যে বলা হয়েছে, পরীক্ষা করার জন্য যদি objপুনরাবৃত্তিযোগ্য হয় তবে এটি করা

obj != null && typeof obj[Symbol.iterator] === 'function' 

Answerতিহাসিক উত্তর (আর বৈধ নয়)

for..ofকনস্ট্রাক্ট ECMAScript 6 ষ্ঠ সংস্করণ ভাষা নির্দিষ্টকরণ খসড়া অংশ। সুতরাং এটি চূড়ান্ত সংস্করণ আগে পরিবর্তন করতে পারে।

এই খসড়াটিতে, পুনরাবৃত্তিযোগ্য অবজেক্টগুলির iteratorএকটি সম্পত্তি হিসাবে ফাংশন থাকতে হবে ।

কোনও জিনিস এর মতো পুনরাবৃত্তিযোগ্য কিনা তা আপনি পরীক্ষা করতে পারেন:

function isIterable(obj){
   if(obj === undefined || obj === null){
      return false;
   }
   return obj.iterator !== undefined;
}

7
পুনরুক্তি করা সম্পত্তিটি ছিল একটি অস্থায়ী ফায়ারফক্স জিনিস। এটি ES6 অনুগত নয়। দেখুন: বিকাশকারী.মোজিলা.আর.ইন
আমির আরাদ

2

জন্য ASYNC iterators আপনি 'Symbol.iterator' এর পরিবর্তে 'Symbol.asyncIterator' এর জন্য পরীক্ষা করা উচিত:

async function* doSomething(i) {
    yield 1;
    yield 2;
}

let obj = doSomething();

console.log(typeof obj[Symbol.iterator] === 'function');      // false
console.log(typeof obj[Symbol.asyncIterator] === 'function'); // true

1

আপনি যদি ভেরিয়েবলটি কোনও অবজেক্ট ( {key: value}) বা একটি অ্যারে ( [value, value]) হয় কিনা তা যদি পরীক্ষা করতে চান তবে আপনি এটি করতে পারেন:

const isArray = function (a) {
    return Array.isArray(a);
};

const isObject = function (o) {
    return o === Object(o) && !isArray(o) && typeof o !== 'function';
};

function isIterable(variable) {
    return isArray(variable) || isObject(variable);
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.