কেন পার্সেন্টে অ্যারে # ম্যাপের সাহায্যে NaN পাওয়া যায়?


290

থেকে মজিলা ডেভেলপার নেটওয়ার্ক :

[1,4,9].map(Math.sqrt)

ফলন হবে:

[1,2,3]

তাহলে কেন এটি করে:

['1','2','3'].map(parseInt)

এই ফলন:

[1, NaN, NaN]

আমি ফায়ারফক্স 3.0.০.১ এবং ক্রোম ০.০ এ পরীক্ষা করেছি এবং কেবল একটি অস্বীকার হিসাবে, আমি জানি এটি ক্রস-ব্রাউজার কার্যকারিতা নয় (কোনও আইই নয়)।

আমি খুঁজে পেয়েছি যে নিম্নলিখিতগুলি পছন্দসই প্রভাবটি সম্পাদন করবে। তবে এটি এখনও এর ভ্রান্ত আচরণের ব্যাখ্যা দেয় না parseInt

['1','2','3'].map(function(i){return +i;}) // returns [1,2,3]

15
.map(parseFloat)অলসতার জন্য : ব্যবহার করুন কারণ এটি অনন্য একটি প্যারামিটার নেয়।

63
বা ব্যবহার .map(Number)
নিকোলাই

2
আপনি যদি কোনও হাত-ঘূর্ণিত ক্রিয়া ছাড়াই পূর্ণসংখ্যার চান তবে আপনি arr.map করতে পারেন (ম্যাথ.ফ্লুর)।
ডান্ডাভিস

@ নিকোলাই ব্যবহারকারী 669677 দুর্দান্ত পরামর্শ! আমি এটি একটি উত্সাহে উত্সাহিত করতে চাই
BiAiB

যে কেউ ব্যাখ্যা করতে পারে কেন পার্সেন্ট প্রথম সংখ্যাকে সঠিকভাবে পার্স করে এবং প্রথম সূচক ব্যতীত অন্যদের জন্য ত্রুটি করে
বাওয়া জি

উত্তর:


478

মধ্যে কলব্যাক ফাংশন Array.mapরয়েছে তিনটি প্যারামিটার:

আপনি যে লিঙ্কটিতে লিঙ্ক করেছেন একই মজিলা পৃষ্ঠা থেকে:

কলব্যাকটি তিনটি আর্গুমেন্টের সাথে আহ্বান জানানো হয়েছে: উপাদানটির মান, উপাদানটির সূচক এবং অ্যারে অবজেক্টকে বিভ্রান্ত করা হচ্ছে "

সুতরাং আপনি যদি এমন কোনও ফাংশন কল করেন parseIntযা আসলে দুটি আর্গুমেন্টের প্রত্যাশা করে, দ্বিতীয় আর্গুমেন্টটি উপাদানটির সূচক হবে।

এই ক্ষেত্রে, আপনি পরিবর্তে parseInt0, 1 এবং 2 এর সাথে কলিং শেষ করেছেন। প্রথমটি প্যারামিটার সরবরাহ না করার মতো একই, সুতরাং এটি ইনপুট (বেস 10, এই ক্ষেত্রে) এর উপর ভিত্তি করে খেলাপি হয়েছিল। বেস 1 একটি অসম্ভব সংখ্যা সংখ্যা, এবং 3 বেস 2 তে একটি বৈধ সংখ্যা নয়:

parseInt('1', 0); // OK - gives 1
parseInt('2', 1); // FAIL - 1 isn't a legal radix
parseInt('3', 2); // FAIL - 3 isn't legal in base 2 

সুতরাং এই ক্ষেত্রে, আপনার মোড়ক ফাংশন প্রয়োজন:

['1','2','3'].map(function(num) { return parseInt(num, 10); });

বা ES2015 + সিনট্যাক্স সহ:

['1','2','3'].map(num => parseInt(num, 10));

(উভয় ক্ষেত্রেই স্পষ্টভাবেparseInt প্রদর্শিত হিসাবে র‌্যাডিক্স সরবরাহ করা ভাল , কারণ অন্যথায় এটি ইনপুটের উপর ভিত্তি করে র‌ডিক্সের অনুমান করে some যদি স্ট্রিংটি শুরু হয় তবে হেক্স অনুমান করুন 0x)


25

map২ য় তর্ক যুক্ত করে চলেছে, যা (বেশিরভাগ ক্ষেত্রেই) গোলযোগের parseIntরেডিক্স প্যারামিটারে রয়েছে।

আপনি যদি আন্ডারস্কোর ব্যবহার করছেন তবে আপনি এটি করতে পারেন:

['10','1','100'].map(_.partial(parseInt, _, 10))

বা আন্ডারস্কোর ছাড়াই:

['10','1','100'].map(function(x) { return parseInt(x, 10); });


18

সংখ্যাটি পুনরাবৃত্তি ফাংশন হিসাবে ব্যবহার করে আপনি এই সমস্যার সমাধান করতে পারেন :

var a = ['0', '1', '2', '10', '15', '57'].map(Number);

console.log(a);

নতুন অপারেটর ব্যতীত, নম্বরটি ধরণের রূপান্তর সম্পাদন করতে ব্যবহৃত হতে পারে। তবে এটি পার্সিয়ান্ট থেকে পৃথক: এটি স্ট্রিংকে বিশ্লেষণ করে না এবং যদি নম্বর রূপান্তর করা না যায় তবে NaN প্রদান করে। এই ক্ষেত্রে:

console.log(parseInt("19asdf"));
console.log(Number("19asf"));


11

আমি বাজি রাখতে যাচ্ছি যে এটি পার্সইন্টের ২ য় প্যারামিটার, রেডিক্সের সাথে মজার কিছু চলছে। এটি অ্যারে.ম্যাপ ব্যবহার করে কেন ভেঙে যাচ্ছে এবং আপনি যখন সরাসরি ডেকেছেন, আমি জানি না।

//  Works fine
parseInt( 4 );
parseInt( 9 );

//  Breaks!  Why?
[1,4,9].map( parseInt );

//  Fixes the problem
[1,4,9].map( function( num ){ return parseInt( num, 10 ) } );

1
পার্সইন্ট কেবলমাত্র অষ্টাল ধরে নেয় যদি সরবরাহিত স্ট্রিং 0 টি অক্ষর দিয়ে শুরু হয়।
Alnitak

ওহ ইয়া ... ঠিক আছে। এটি ইনপুটটির উপর ভিত্তি করে রডিক্সটিকে "অনুমান" করার চেষ্টা করে। এর জন্যে দুঃখিত.
পিটার বেইলি

3

আপনি তীর ফাংশন ES2015 / ES6 ব্যবহার করতে পারেন এবং কেবল পার্সেইন্টে নম্বর পাস করতে পারেন। রেডিক্সের জন্য ডিফল্ট মান 10 হবে

[10, 20, 30].map(x => parseInt(x))

অথবা আপনি আপনার কোডের আরও ভাল পঠনযোগ্যতার জন্য স্পষ্টভাবে Radix নির্দিষ্ট করতে পারেন।

[10, 20, 30].map(x => parseInt(x, 10))

উপরের উদাহরণস্বরূপ র‌্যাডিক্স স্পষ্টভাবে 10 এ সেট করুন


1

আরেকটি (কাজ করা) দ্রুত সমাধান:

var parseInt10 = function(x){return parseInt(x, 10);}

['0', '1', '2', '10', '15', '57'].map(parseInt10);
//[0, 1, 2, 10, 15, 57]

0

parseIntএই কারণেই আইএমএইচও এড়ানো উচিত। এই জাতীয় প্রসঙ্গে এইটিকে আরও সুরক্ষিত করতে আপনি এটিকে মোড়ানো করতে পারেন:

const safe = {
  parseInt: (s, opt) => {
    const { radix = 10 } = opt ? opt : {};
    return parseInt(s, radix);
  }
}

console.log( ['1','2','3'].map(safe.parseInt) );
console.log(
  ['1', '10', '11'].map(e => safe.parseInt(e, { radix: 2 }))
);

লড্যাশ / এফপি ক্যাপগুলি পুনরায় ডিগ্রিটি হিসাবে এই গোটাচসগুলি এড়াতে পুনরায় যুক্তি দেয়। ব্যক্তিগতভাবে আমি এগুলি এড়াতে যত বেশি বাগ তৈরি করতে এই কাজের সন্ধান পেয়েছি। parseIntনিরাপদ বাস্তবায়নের পক্ষে ব্ল্যাকলিস্টিং , আমি মনে করি, এটি একটি আরও ভাল পদ্ধতির approach

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