ব্যবহারিক উপায়
আমি মনে করি যে একটি নির্দিষ্ট প্রয়োগটি "ভুল" সমাধানের বিপরীতে যদি কেবল "সঠিক" ("সঠিক") হয় তবে "সঠিক পথ ™" বলা ভুল। টোমের সমাধানটি স্ট্রিং-ভিত্তিক অ্যারে তুলনার তুলনায় সুস্পষ্ট উন্নতি, তবে এর অর্থ এটি উদ্দেশ্যমূলকভাবে "সঠিক" নয় " কি অধিকার যাহাই হউক না কেন? এটি কি দ্রুততম? এটি কি সবচেয়ে নমনীয়? এটা বোঝা সবচেয়ে সহজ? এটি ডিবাগ করার দ্রুততম কি? এটি কি সর্বনিম্ন অপারেশনগুলি ব্যবহার করে? এর কি কোনও পার্শ্ব প্রতিক্রিয়া আছে? কোন একটি সমাধান সব জিনিস সেরা হতে পারে।
টমস তার সমাধানটি দ্রুত বলতে পারে তবে আমি এটিও বলব যে এটি অযথা জটিল। এটি একটি সর্বস্তর সমাধান হতে চেষ্টা করে যা সমস্ত অ্যারে বাসা বাঁধার জন্য বা না করে কাজ করে। আসলে, এটি এমনকি ইনপুট হিসাবে কেবল অ্যারের চেয়েও বেশি গ্রহণ করে এবং এখনও একটি "বৈধ" উত্তর দেওয়ার চেষ্টা করে।
জেনারিকস পুনরায় ব্যবহারযোগ্যতার প্রস্তাব দেয়
আমার উত্তর সমস্যাটি ভিন্নভাবে পৌঁছে দেবে। আমি একটি জেনেরিক arrayCompare
প্রক্রিয়া শুরু করব যা কেবল অ্যারেগুলিতে পদক্ষেপ নেওয়ার সাথে সম্পর্কিত। সেখান থেকে আমরা আমাদের অন্যান্য মৌলিক তুলনা ফাংশনগুলি তৈরি করব arrayEqual
এবং arrayDeepEqual
ইত্যাদি
// arrayCompare :: (a -> a -> Bool) -> [a] -> [a] -> Bool
const arrayCompare = f => ([x,...xs]) => ([y,...ys]) =>
x === undefined && y === undefined
? true
: Boolean (f (x) (y)) && arrayCompare (f) (xs) (ys)
আমার মতে, সেরা ধরণের কোডের এমনকি মন্তব্যগুলিরও প্রয়োজন হয় না এবং এটি কোনও ব্যতিক্রম নয়। এখানে খুব সামান্য ঘটনা ঘটছে যে আপনি প্রায় কোনও প্রচেষ্টা ছাড়াই এই পদ্ধতির আচরণ বুঝতে পারবেন। অবশ্যই, কিছু ES6 সিনট্যাক্স আপনার কাছে এখন বিদেশী বলে মনে হতে পারে তবে এটি কেবল কারণ ES6 অপেক্ষাকৃত নতুন।
প্রকারটি যেমন প্রস্তাব দেয়, arrayCompare
তুলনা ফাংশন নেয় f
এবং দুটি ইনপুট অ্যারে xs
এবং ys
। বেশিরভাগ ক্ষেত্রে, আমরা যা করি তা হ'ল f (x) (y)
ইনপুট অ্যারেগুলির প্রতিটি উপাদানকে কল করা । আমরা সংক্ষিপ্ত-সার্কিট মূল্যায়নের জন্য ধন্যবাদ - false
যদি ব্যবহারকারী সংজ্ঞায়িত f
ফেরত দেয় তবে আমরা তাড়াতাড়ি ফিরে আসি। হ্যাঁ, এর অর্থ এটি হল তুলনাকারী পুনরুত্থানগুলি বন্ধ করতে পারে এবং অপ্রয়োজনীয় হলে বাকী ইনপুট অ্যারের মাধ্যমে লুপিং রোধ করতে পারে।false
&&
কঠোর তুলনা
এর পরে, আমাদের arrayCompare
ফাংশনটি ব্যবহার করে আমরা সহজেই আমাদের প্রয়োজন অন্যান্য ফাংশন তৈরি করতে পারি। আমরা প্রাথমিক দিয়ে শুরু করব arrayEqual
...
// equal :: a -> a -> Bool
const equal = x => y =>
x === y // notice: triple equal
// arrayEqual :: [a] -> [a] -> Bool
const arrayEqual =
arrayCompare (equal)
const xs = [1,2,3]
const ys = [1,2,3]
console.log (arrayEqual (xs) (ys)) //=> true
// (1 === 1) && (2 === 2) && (3 === 3) //=> true
const zs = ['1','2','3']
console.log (arrayEqual (xs) (zs)) //=> false
// (1 === '1') //=> false
যে হিসাবে সহজ। arrayEqual
সঙ্গে সংজ্ঞায়িত করা যায় arrayCompare
এবং একটি comparator ফাংশন যা তুলনা a
করতে b
ব্যবহার ===
(প্রখর সমতা জন্য)।
লক্ষ্য করুন যে আমরা equal
এটির নিজস্ব কার্যকারিতা হিসাবেও সংজ্ঞা দিই । এটি arrayCompare
অন্য ডেটা টাইপের (অ্যারে) প্রসঙ্গে আমাদের প্রথম অর্ডার তুলককে কাজে লাগানোর জন্য উচ্চ-অর্ডার ক্রিয়াকলাপের ভূমিকাটিকে হাইলাইট করে ।
আলগা তুলনা
আমরা শুধু সহজে সংজ্ঞায়িত পারে arrayLooseEqual
একটি ব্যবহার ==
পরিবর্তে। এখন 1
(সংখ্যা) সাথে '1'
(স্ট্রিং) তুলনা করার সময় ফলাফলটি হবে true
…
// looseEqual :: a -> a -> Bool
const looseEqual = x => y =>
x == y // notice: double equal
// arrayLooseEqual :: [a] -> [a] -> Bool
const arrayLooseEqual =
arrayCompare (looseEqual)
const xs = [1,2,3]
const ys = ['1','2','3']
console.log (arrayLooseEqual (xs) (ys)) //=> true
// (1 == '1') && (2 == '2') && (3 == '3') //=> true
গভীর তুলনা (পুনরাবৃত্ত)
আপনি সম্ভবত লক্ষ্য করেছেন যে এটি কেবল অগভীর তুলনা। নিশ্চয় টমের সমাধান "সঠিক পথ ™" কারণ এটি নিবিড় গভীর তুলনা করে, তাই না?
ভাল, আমাদের arrayCompare
পদ্ধতিটি এমন একটি উপায়ে ব্যবহারের পক্ষে যথেষ্ট বহুমুখী যা গভীর সমতা পরীক্ষাকে একটি বাতাস তৈরি করে…
// isArray :: a -> Bool
const isArray =
Array.isArray
// arrayDeepCompare :: (a -> a -> Bool) -> [a] -> [a] -> Bool
const arrayDeepCompare = f =>
arrayCompare (a => b =>
isArray (a) && isArray (b)
? arrayDeepCompare (f) (a) (b)
: f (a) (b))
const xs = [1,[2,[3]]]
const ys = [1,[2,['3']]]
console.log (arrayDeepCompare (equal) (xs) (ys)) //=> false
// (1 === 1) && (2 === 2) && (3 === '3') //=> false
console.log (arrayDeepCompare (looseEqual) (xs) (ys)) //=> true
// (1 == 1) && (2 == 2) && (3 == '3') //=> true
যে হিসাবে সহজ। আমরা আরও একটি উচ্চতর অর্ডার ফাংশন ব্যবহার করে একটি গভীর তুলনামূলক তৈরি করি । এই সময় আমরা মোড়কে করছি arrayCompare
যে যদি চেক করবে একটি কাস্টম comparator ব্যবহার a
এবং b
অ্যারে আছে। যদি তা হয় তবে arrayDeepCompare
অন্যথায় পুনরায় আবেদন করুন a
এবং b
ব্যবহারকারী-নির্দিষ্ট করা তুলনা ( f
) এর সাথে তুলনা করুন । এটি আমাদের পৃথক উপাদানগুলিকে আসলে কীভাবে তুলনা করে তার থেকে গভীর তুলনা আচরণকে আলাদা রাখতে দেয়। অর্থাত, শো উপরোক্ত উদাহরণে মতো আমরা গভীর ব্যবহার তুলনা করতে পারবেন equal
, looseEqual
, বা অন্য কোন comparator আমরা ভুলবেন না।
কারণ arrayDeepCompare
তরকারিযুক্ত, আমরা পূর্ববর্তী উদাহরণগুলিতেও এর মতো আংশিকভাবে প্রয়োগ করতে পারি
// arrayDeepEqual :: [a] -> [a] -> Bool
const arrayDeepEqual =
arrayDeepCompare (equal)
// arrayDeepLooseEqual :: [a] -> [a] -> Bool
const arrayDeepLooseEqual =
arrayDeepCompare (looseEqual)
আমার কাছে টোমের সমাধানের তুলনায় এটি ইতিমধ্যে সুস্পষ্ট উন্নতি কারণ প্রয়োজনীয় হিসাবে আমি পরিষ্কারভাবে আমার অ্যারেগুলির জন্য অগভীর বা গভীর তুলনা বেছে নিতে পারি।
বস্তুর তুলনা (উদাহরণ)
এখন যদি আপনার কাছে কিছু জিনিস বা কিছু থাকে? আপনি যদি সেই অ্যারেগুলিকে "সমান" হিসাবে বিবেচনা করতে চান তবে প্রতিটি বস্তুর একই id
মান থাকে ...
// idEqual :: {id: Number} -> {id: Number} -> Bool
const idEqual = x => y =>
x.id !== undefined && x.id === y.id
// arrayIdEqual :: [a] -> [a] -> Bool
const arrayIdEqual =
arrayCompare (idEqual)
const xs = [{id:1}, {id:2}]
const ys = [{id:1}, {id:2}]
console.log (arrayIdEqual (xs) (ys)) //=> true
// (1 === 1) && (2 === 2) //=> true
const zs = [{id:1}, {id:6}]
console.log (arrayIdEqual (xs) (zs)) //=> false
// (1 === 1) && (2 === 6) //=> false
যে হিসাবে সহজ। এখানে আমি ভ্যানিলা জেএস অবজেক্ট ব্যবহার করেছি তবে এই ধরণের তুলনামূলক যে কোনও অবজেক্টের জন্য কাজ করতে পারে ; এমনকি আপনার কাস্টম অবজেক্ট। এই ধরণের সাম্যতা পরীক্ষাকে সমর্থন করার জন্য টমের সমাধানটিকে সম্পূর্ণভাবে পুনরায় কাজ করা দরকার
বস্তুর সাথে গভীর অ্যারে? কোন সমস্যা নেই. আমরা অত্যন্ত বহুমুখী, জেনেরিক ফাংশন তৈরি করেছি, যাতে তারা বিভিন্ন ধরণের ব্যবহারের ক্ষেত্রে কাজ করবে।
const xs = [{id:1}, [{id:2}]]
const ys = [{id:1}, [{id:2}]]
console.log (arrayCompare (idEqual) (xs) (ys)) //=> false
console.log (arrayDeepCompare (idEqual) (xs) (ys)) //=> true
নির্বিচার তুলনা (উদাহরণ)
বা আপনি যদি অন্য কোনও ধরণের সম্পূর্ণ স্বেচ্ছাসেবী তুলনা করতে চান? প্রতিটি আমি প্রত্যেকের x
চেয়ে বড় কিনা তা জানতে চাই y
...
// gt :: Number -> Number -> Bool
const gt = x => y =>
x > y
// arrayGt :: [a] -> [a] -> Bool
const arrayGt = arrayCompare (gt)
const xs = [5,10,20]
const ys = [2,4,8]
console.log (arrayGt (xs) (ys)) //=> true
// (5 > 2) && (10 > 4) && (20 > 8) //=> true
const zs = [6,12,24]
console.log (arrayGt (xs) (zs)) //=> false
// (5 > 6) //=> false
কমই বেশি
আপনি দেখতে পাচ্ছেন আমরা আসলে কম কোড দিয়ে আরও কিছু করছি। arrayCompare
নিজের সম্পর্কে জটিল কিছু নেই এবং আমরা তৈরি কাস্টম তুলকগুলির একটি খুব সাধারণ বাস্তবায়ন হয়েছে।
স্বচ্ছন্দে সঙ্গে, আমরা সংজ্ঞায়িত করতে পারেন ঠিক দুইটি অ্যারের তুলনা করা যেতে করার জন্য আমরা কিভাবে ইচ্ছুক - অগভীর, গভীর, কঠোর, আলগা, কিছু বস্তু সম্পত্তি, অথবা কিছু নির্বিচারে গণনার, অথবা এইসব কোনো সমন্বয় - সব এক পদ্ধতি ব্যবহার করে , arrayCompare
। এমনকি স্বপ্ন RegExp
তুলনা করতে পারে ! আমি জানি বাচ্চারা কীভাবে এই পুনঃসংশ্লিষ্টগুলিকে ভালবাসে ...
এটি কি দ্রুততম? নাঃ। তবে এটি সম্ভবত হওয়ার দরকার নেই। গতি যদি আমাদের কোডের মান পরিমাপ করতে ব্যবহৃত একমাত্র মেট্রিক হয় তবে প্রচুর দুর্দান্ত কোড ফেলে দেওয়া হবে - এজন্যই আমি এই পদ্ধতির প্র্যাকটিকাল ওয়ে বলছি । বা হতে পারে আরও সুষ্ঠু, একটি প্রাকৃতিক উপায়। এই বিবরণটি এই উত্তরের জন্য উপযুক্ত কারণ আমি বলছি না যে এই উত্তরটি অন্য কোনও উত্তরের তুলনায় কেবল ব্যবহারিক; এটা উদ্দেশ্যমূলকভাবে সত্য। আমরা খুব অল্প কোডের সাথে একটি উচ্চতর ডিগ্রি অর্জন করেছি যার পক্ষে যুক্তিযুক্ত খুব সহজ। অন্য কোনও কোড বলতে পারে না যে আমরা এই বিবরণটি অর্জন করিনি।
এটি কি এটিকে আপনার জন্য "সঠিক" সমাধান হিসাবে তৈরি করে? জন্য যে খবর আপনি সিদ্ধান্ত নিতে। এবং অন্য কেউ আপনার পক্ষে এটি করতে পারে না; আপনার প্রয়োজনগুলি কী তা কেবল আপনি জানেন। প্রায় সব ক্ষেত্রেই আমি চতুর এবং দ্রুত ধরণের চেয়ে সোজা, ব্যবহারিক এবং বহুমুখী কোডকে গুরুত্ব দিয়েছি। আপনি যা মূল্য দেন তার থেকে আলাদা হতে পারে, তাই আপনার জন্য কী কাজ করে তা চয়ন করুন।
সম্পাদন করা
আমার পুরানো উত্তরটি arrayEqual
ক্ষুদ্রতর প্রক্রিয়াগুলিতে ক্ষয় করার দিকে বেশি মনোনিবেশ করেছিল । এটি একটি আকর্ষণীয় অনুশীলন, তবে এই সমস্যাটির কাছে যাওয়ার সর্বোত্তম (সবচেয়ে ব্যবহারিক) উপায় নয়। আপনি যদি আগ্রহী হন তবে আপনি এই পুনর্বিবেচনার ইতিহাসটি দেখতে পারেন।