ප්රායෝගික මාර්ගය
"වැරදි" විසඳුමකට වඩා වෙනස්ව "නිවැරදි මාර්ගය" ("නිවැරදි") නම් විශේෂිත ක්රියාත්මක කිරීමක් "නිවැරදි මාර්ගය" යැයි පැවසීම වැරදියි කියා මම සිතමි. ටොමේගේ විසඳුම නූල් මත පදනම් වූ අරාව සංසන්දනය කිරීමට වඩා පැහැදිලි දියුණුවක් වන නමුත් එයින් අදහස් කරන්නේ එය වෛෂයිකව “හරි” යන්නයි. කුමක්ද නිවැරදි කෙසේ හෝ? එය වේගවත්මද? එය වඩාත් නම්යශීලීද? තේරුම් ගැනීම පහසුම ද? නිදොස් කිරීම ඉක්මන් ද? එය අවම මෙහෙයුම් භාවිතා කරයිද? එහි අතුරු ආබාධ තිබේද? කිසිම විසඳුමකට සෑම දෙයකින්ම හොඳම දේ තිබිය නොහැකිය.
ටොමේට ඔහුගේ විසඳුම වේගවත් යැයි පැවසිය හැකි නමුත් එය අනවශ්ය ලෙස සංකීර්ණ යැයි මම කියමි. එය සියලු අරා සඳහා වැඩ කරන, කූඩු කළ හෝ නොවූ සියලු දෙනාටම විසඳුමක් වීමට උත්සාහ කරයි. ඇත්ත වශයෙන්ම, එය අරා වලට වඩා වැඩි ප්රමාණයක් ආදානයක් ලෙස පිළිගන්නා අතර තවමත් "වලංගු" පිළිතුරක් දීමට උත්සාහ කරයි.
ජනක විද්යාව නැවත භාවිතා කිරීමේ හැකියාව ලබා දෙයි
මගේ පිළිතුර වෙනස් ආකාරයකින් ගැටලුවට එළඹෙනු ඇත. 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'
result ලය වනුයේ 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
පරිශීලක-සදහන් comparator (කිරීමට 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
කුඩා ක්රියා පටිපාටිවලට දිරාපත් වීම කෙරෙහි වැඩි අවධානයක් යොමු කරන ලදී . එය සිත්ගන්නාසුලු ව්යායාමයකි, නමුත් ඇත්ත වශයෙන්ම මෙම ගැටලුවට එළඹිය හැකි හොඳම (වඩාත්ම ප්රායෝගික) ක්රමය නොවේ. ඔබ කැමති නම්, ඔබට මෙම සංශෝධන ඉතිහාසය දැක ගත හැකිය.