জাভাস্ক্রিপ্টে কেস-সংবেদনশীল বাছাই কিভাবে করবেন?


220

আমার কাছে জাভাস্ক্রিপ্টে বাছাই করতে প্রয়োজনীয় স্ট্রিংগুলির একটি অ্যারে রয়েছে, তবে কেস-সংবেদনশীল উপায়ে। এটি কিভাবে সম্পাদন করবেন?

উত্তর:


404

(প্রায় :) একটি ওয়ান-লাইনারে

["Foo", "bar"].sort(function (a, b) {
    return a.toLowerCase().localeCompare(b.toLowerCase());
});

যার ফলাফল

[ 'bar', 'Foo' ]

যদিও

["Foo", "bar"].sort();

ফলাফল স্বরূপ

[ 'Foo', 'bar' ]

9
মনে রাখবেন যে লোকালকম্পেরের উন্নত বিকল্পগুলি এখনও সমস্ত প্ল্যাটফর্ম / ব্রাউজারগুলিতে সমর্থিত নয়। আমি জানি তারা এই উদাহরণে ব্যবহার হয় না, তবে কেবল স্বচ্ছতার জন্য যোগ করতে চেয়েছিলেন। আরও তথ্যের জন্য এমডিএন দেখুন
আইয়াম__

97
আপনি localeCompare () জড়িত করতে যাচ্ছেন, তাহলে ব্যবহার করতে পারে তার কেস-অবশ হতে ক্ষমতা যেমন:return a.localeCompare(b, 'en', {'sensitivity': 'base'});
মাইকেল Dyck

2
ইতিমধ্যে কিছু ক্ষেত্রে ডিফল্টরূপে এটি করার toLowerCase()সময় কল না করার জন্য +1 localeCompare। আপনি এখানে প্যারামিটারগুলি দেওয়ার জন্য আরও পড়তে পারেন: বিকাশকারী.মোজিলা.আর.ইন-
ইউএস

3
রেফারেন্সযুক্ত পৃষ্ঠায় @ মিলিমিট্রিক চুক্তি, সেই বৈশিষ্ট্যটি কিছু ব্রাউজার দ্বারা সমর্থিত নয় (উদাঃ আইই <11 বা সাফারি)। এখানে উল্লিখিত সমাধানটি খুব ভাল, তবে কিছু ব্রাউজারের জন্য ব্যাকপোর্টিং / পলফিল প্রয়োজন।
কে-

2
আপনার যদি একটি বড় অ্যারে থাকে তবে items.sort(new Intl.Collator('en').compare)আরও ভাল পারফরম্যান্সের জন্য এটি ব্যবহার করা বুদ্ধিমান । ( এমডিএন দেখুন ))
ভাল্টলাই

60
myArray.sort(
  function(a, b) {
    if (a.toLowerCase() < b.toLowerCase()) return -1;
    if (a.toLowerCase() > b.toLowerCase()) return 1;
    return 0;
  }
);

সম্পাদনা: দয়া করে নোট করুন যে আমি মূলত এইটি লেখার জন্য মনে রেখে পারফরম্যান্স না করে কৌশলটি বর্ণনা করার জন্য লিখেছিলাম। আরও কমপ্যাক্ট সমাধানের জন্য দয়া করে @ ইভান ক্রেচেতোভের উত্তরটি দেখুন।


3
এটি toLowerCaseপ্রতিটি স্ট্রিংয়ে দু'বার কল করতে পারে ; ভেরিয়েবলগুলিতে স্ট্রিংয়ের নিম্ন সংস্করণগুলি সঞ্চিত করতে আরও দক্ষ হবে।
জ্যাকব

সত্য এবং ধন্যবাদ। আমি পারফরম্যান্স নয়, মন দিয়ে স্পষ্ট করে এই লিখেছি। আমার ধারণা আমি এটি নোট করা উচিত।
রন টর্নেম্ব

1
@ জ্যাকব ন্যায্য হওয়ার জন্য গৃহীত উত্তরের একই বুনিয়াদি সমস্যা রয়েছে: এটি .toLowerCase()অ্যারেতে প্রতিটি আইটেমের জন্য সম্ভবত একাধিকবার কল করতে পারে । উদাহরণস্বরূপ, বিপরীত ক্রমে 10 টি আইটেম বাছাই করার সময় তুলনা ফাংশনটিতে 45 ​​টি কল। var i = 0; ["z","y","x","w","v","u","t","s","r","q"].sort(function (a, b) {++i; return a.toLowerCase().localeCompare(b.toLowerCase());}); console.log("Calls to Compare: " + i); // i === 45
অযৌক্তিকভাবে

47

এই পুরানো প্রশ্নটি পুনর্বিবেচনার সময় এসেছে।

আপনার উপর নির্ভর করে সমাধানগুলি ব্যবহার করা উচিত নয় toLowerCase। এগুলি অদক্ষ এবং কিছু ভাষায় কেবল কাজ করে না (উদাহরণস্বরূপ তুর্কি)। এটি পছন্দ করুন:

['Foo', 'bar'].sort((a, b) => a.localeCompare(b, undefined, {sensitivity: 'base'}))

ব্রাউজারের সামঞ্জস্যের জন্য ডকুমেন্টেশন এবং sensitivityবিকল্প সম্পর্কে জানার জন্য যাচাই করুন Check


1
সাবধানতা অবলম্বন করুন, এটি সমস্ত জাভাস্ক্রিপ্ট ইঞ্জিনগুলিতে সমর্থিত নয়।
Luboš Turek

26
arr.sort(function(a,b) {
    a = a.toLowerCase();
    b = b.toLowerCase();
    if (a == b) return 0;
    if (a > b) return 1;
    return -1;
});

1
বাreturn a === b ? 0 : a > b ? 1 : -1;
ডেভিন জি রোড

এটি সম্ভবত সংখ্যার প্রতিনিধিত্বকারী স্ট্রিংগুলির উদ্দেশ্যে হিসাবে কাজ করবে না । পাটিগণিত অপারেটরগুলি স্ট্রিংয়ের পরিবর্তে সংখ্যার শব্দার্থক ব্যবহার করবে। উদাহরণস্বরূপ, যদি আমাদের থাকে ["111", "33"], আমরা এটি ফিরে আসতে চাই ["111", "33"]কারণ অক্ষর কোড ক্রমে 1 এর আগে 3 আসে। যাইহোক, এই উত্তর ফাংশন ফিরে আসবে ["33", "111"]কারণ সংখ্যা 33সংখ্যার চেয়ে কম হয় 111
অস্টিন ডেভিস

@ অস্টিনড্যাভিস "33" > "111" === trueএবং 33 > 111 === false। এটি উদ্দেশ্য হিসাবে কাজ করে।
নিট দ্য ডার্ক আবসোল

12

আপনি Intl.Collator().compareএমডিএন প্রতি নতুন ব্যবহার করতে পারেন , অ্যারে বাছাই করার সময় এটি আরও কার্যকর efficient খারাপ দিকটি এটি পুরানো ব্রাউজারগুলির দ্বারা সমর্থিত নয়। এমডিএন জানিয়েছে যে এটি সাফারিতে মোটেই সমর্থিত নয়। এটি যাচাই করা দরকার, যেহেতু এতে বলা আছে যে Intl.Collatorসমর্থিত।

বড় সংখ্যক স্ট্রিং যেমন বড় অ্যারে বাছাইয়ের সাথে তুলনা করার সময়, একটি ইন্টেল.ক্লেটর অবজেক্ট তৈরি করা এবং তার তুলনামূলক সম্পত্তি দ্বারা প্রদত্ত ফাংশনটি ব্যবহার করা ভাল is

["Foo", "bar"].sort(Intl.Collator().compare); //["bar", "Foo"]

11

আপনি যদি ইনপুট অ্যারেতে উপাদানের ক্রম নির্বিশেষে একই ক্রমের গ্যারান্টি দিতে চান তবে এখানে একটি স্থিতিশীল বাছাই করা হচ্ছে:

myArray.sort(function(a, b) {
    /* Storing case insensitive comparison */
    var comparison = a.toLowerCase().localeCompare(b.toLowerCase());
    /* If strings are equal in case insensitive comparison */
    if (comparison === 0) {
        /* Return case sensitive comparison instead */
        return a.localeCompare(b);
    }
    /* Otherwise return result */
    return comparison;
});

5

মামলা স্বাভাবিক .sort()সঙ্গে .toLowerCase()


4

আপনি এলভিস অপারেটরটিও ব্যবহার করতে পারেন:

arr = ['Bob', 'charley', 'fudge', 'Fudge', 'biscuit'];
arr.sort(function(s1, s2){
    var l=s1.toLowerCase(), m=s2.toLowerCase();
    return l===m?0:l>m?1:-1;
});
console.log(arr);

দেয়:

biscuit,Bob,charley,fudge,Fudge

লোকালকম্পের পদ্ধতিটি সম্ভবত ঠিক আছে যদিও ...

দ্রষ্টব্য: এলভিস অপারেটর একটি সংক্ষিপ্ত ফর্ম 'টের্নারি অপারেটর' অন্যথায় যদি হয় তবে সাধারণত অ্যাসাইনমেন্ট সহ।
আপনি যদি?: পাশের দিকে তাকান তবে এটি এলভিসের মতো দেখাচ্ছে ... এর
পরিবর্তে:

if (y) {
  x = 1;
} else {
  x = 2;
}

তুমি ব্যবহার করতে পার:

x = y?1:2;

অর্থাত্ যখন y সত্য হয়, তারপরে 1 (x এ্যাসাইনমেন্টের জন্য) ফিরে আসুন, অন্যথায় 2 (x এ্যাসাইনমেন্টের জন্য) প্রদান করুন।


5
পেডেন্টিক হতে, এটি এলভিস অপারেটর নয়। এটি কেবলমাত্র একটি বেসিক টেরিনারি অপারেটর। সত্যিকারের এলভিস অপারেটর নাল-কোয়েলসিং, উদাহরণস্বরূপ, পরিবর্তে x = y ? y : z, আপনি এটি করতে পারেন x = y ?: z। জাভাস্ক্রিপ্টের প্রকৃত এলভিস অপারেটর নেই, তবে আপনি x = y || zএকই ধরণের ব্যবহার করতে পারেন ।
চার্লস উড

3

অন্যান্য উত্তরগুলি ধরে নিয়েছে যে অ্যারেটিতে স্ট্রিং রয়েছে। আমার পদ্ধতিটি আরও ভাল, কারণ অ্যারেতে নাল, অপরিজ্ঞাত বা অন্যান্য অ-স্ট্রিং থাকলেও এটি কাজ করবে।

var notdefined;
var myarray = ['a', 'c', null, notdefined, 'nulk', 'BYE', 'nulm'];

myarray.sort(ignoreCase);

alert(JSON.stringify(myarray));    // show the result

function ignoreCase(a,b) {
    return (''+a).toUpperCase() < (''+b).toUpperCase() ? -1 : 1;
}

null'Nulk' এবং 'nulm' মধ্যে সাজানো হবে। তবে সর্বদা সর্বদা বাছাই করা undefinedহবে ।


(''+notdefined) === "undefined"সুতরাং এটি "জেড" এর আগে বাছাই হবে
ম্যাটডব্লিউ

অনুমান করা উচিত আমার সংজ্ঞাটি সন্ধান করা উচিত Array.prototype.sort: | কারণ অংশটি (''+notdefined) === "undefined" সত্যিই সত্য ... যার অর্থ যদি আপনি ক্রমটি বিপরীত করতে বাছাই ফাংশনে -1 এবং 1 টি উল্টান, অপরিবর্তিত এখনও শেষ পর্যন্ত সাজান orts অ্যারে বাছাইয়ের প্রেক্ষাপটের বাইরে তুলনা ফাংশনটি ব্যবহার করার সময় এটিও বিবেচনা করা উচিত (আমি যখন এই প্রশ্নের আগে এসেছি তখন)।
MattW

এবং এখন সেই Array.prototype.sortসংজ্ঞাটি নিয়ে ভাবনা করেছেন - আরও কয়েকটি মন্তব্য। প্রথমত, (''+a)- toString()ইসকামাস্ক্রিপ্টের তুলনামূলকভাবে তাদের পাস করার আগে উপাদানগুলিতে ডাকতে হবে - এর দরকার নেই । দ্বিতীয়ত, সমান (তুল্য-সমান-ক্ষেত্রে-সহ) স্ট্রিংগুলির তুলনা করার সময় যে ignoreCaseরিটার্নটি আসে 1তার অর্থ হ'ল ডুপ্লিকেট মানগুলি থাকলে স্পেসিফিকেশন ফলাফলটিকে সংজ্ঞায়িত করে না (সম্ভবত কিছু অপ্রয়োজনীয় অদলবদল ঘটলে ঠিক হবে), আমি মনে করি।
ম্যাটডব্লিউ

@MattW, এটা আমার মনে হচ্ছে যে undefinedএকটি বিশেষ ক্ষেত্রে, যার জন্য হয় কোনো এক্স এক্স <অনির্ধারিত ও এক্স> অনির্ধারিত হয় উভয় মিথ্যা । যে undefinedসবসময় গত হয়, সাজানোর সাজানোর প্রয়োগের একটি উপজাত হয়। আমি ('' + ক) কে কেবল একটিতে পরিবর্তন করার চেষ্টা করেছি, তবে এটি ব্যর্থ হয়। আমি পাই TypeError: a.toUpperCase is not a function। আপাতদৃষ্টিতে তুলনাFn কল করার আগে বলা toStringহয় না
জন হেন্কেল

1
আহ, ঠিক আছে, এটি সঠিক ধারণা দেয়। জন্য undefinedcompareFn হয় নামক কখনো
জন Henckel


1

স্বীকৃত উত্তরের সমর্থনে আমি যোগ করতে চাই যে নীচের ফাংশনটি মূল অ্যারে মানগুলি বাছাই করতে পরিবর্তিত করবে বলে মনে হচ্ছে যাতে এটি কেবল ছোট হাতের ক্ষেত্রেই বাছাই করে না তবে উপরের ক্ষেত্রে মানগুলিও ছোট ক্ষেত্রে পরিবর্তিত হবে। এটি আমার জন্য সমস্যা কারণ যদিও আমি মেরিকে মেরির পাশে দেখতে চাইলেও আমি চাই না যে মরিয়মের প্রথম মানটি কেস কে ছোট ক্ষেত্রে বদলে দেওয়া হোক।

myArray.sort(
  function(a, b) {
    if (a.toLowerCase() < b.toLowerCase()) return -1;
    if (a.toLowerCase() > b.toLowerCase()) return 1;
    return 0;
  }
);

আমার পরীক্ষায়, গৃহীত উত্তর থেকে নিম্নলিখিত ফাংশনটি সঠিকভাবে সাজানো হয়েছে তবে মানগুলি পরিবর্তন করে না।

["Foo", "bar"].sort(function (a, b) {
    return a.toLowerCase().localeCompare(b.toLowerCase());
});

0

আপনি বুঝতে চেষ্টা করলে এটি সহায়তা করতে পারে:

var array = ["sort", "Me", "alphabetically", "But", "Ignore", "case"];
console.log('Unordered array ---', array, '------------');

array.sort(function(a,b) {
    a = a.toLowerCase();
    b = b.toLowerCase();
    console.log("Compare '" + a + "' and '" + b + "'");

    if( a == b) {
        console.log('Comparison result, 0 --- leave as is ');
        return 0;
    }
    if( a > b) {
        console.log('Comparison result, 1 --- move '+b+' to before '+a+' ');
        return 1;
    }
    console.log('Comparison result, -1 --- move '+a+' to before '+b+' ');
    return -1;


});

console.log('Ordered array ---', array, '------------');


// return logic

/***
If compareFunction(a, b) is less than 0, sort a to a lower index than b, i.e. a comes first.
If compareFunction(a, b) returns 0, leave a and b unchanged with respect to each other, but sorted with respect to all different elements. Note: the ECMAscript standard does not guarantee this behaviour, and thus not all browsers (e.g. Mozilla versions dating back to at least 2003) respect this.
If compareFunction(a, b) is greater than 0, sort b to a lower index than a.
***/

http://jsfiddle.net/ianjamieson/wmxn2ram/1/


0
arr.sort(function(a,b) {
    a = a.toLowerCase();
    b = b.toLowerCase();
    if( a == b) return 0;
    if( a > b) return 1;
    return -1;
});

উপরের ফাংশনে, আমরা যদি কেবল ছোট হাতের তুলনা করি তখন দুটি এবং ক এর মান খুব ভাল ফলাফল হয় না।

উদাহরণস্বরূপ, যদি অ্যারে [A, a, B, b, c, C, D, d, e, E] হয় এবং আমরা উপরের ফাংশনটি ব্যবহার করি, আমাদের ঠিক সেই অ্যারে আছে। এটি কিছুই পরিবর্তন হয়নি।

ফলাফলটি হ'ল [এ, এ, বি, বি, সি, সি, ডি, ডি, ই, ই], যখন দুটি নিম্ন কেসের মান সমান হয় তখন আমাদের আবার তুলনা করা উচিত:

function caseInsensitiveComparator(valueA, valueB) {
    var valueALowerCase = valueA.toLowerCase();
    var valueBLowerCase = valueB.toLowerCase();

    if (valueALowerCase < valueBLowerCase) {
        return -1;
    } else if (valueALowerCase > valueBLowerCase) {
        return 1;
    } else { //valueALowerCase === valueBLowerCase
        if (valueA < valueB) {
            return -1;
        } else if (valueA > valueB) {
            return 1;
        } else {
            return 0;
        }
    }
}

-1

আমি উপরের উত্তরটি একটি পলিফিলের সাথে আবৃত করেছি যাতে আমি স্ট্রিং অ্যারেগুলিতে .sortIgnoreCase () কল করতে পারি can

// Array.sortIgnoreCase() polyfill
if (!Array.prototype.sortIgnoreCase) {
    Array.prototype.sortIgnoreCase = function () {
        return this.sort(function (a, b) {
            return a.toLowerCase().localeCompare(b.toLowerCase());
        });
    };
}

কখনও কখনও এটি করবেন না দয়া করে। কেবলমাত্র আপনার নিজের জিনিসগুলির প্রোটোটাইপটি পরিবর্তন করুন। এটি কোনও পলিফিলও নয়, কারণ এই অ্যারে পদ্ধতিটি ইসমাস্ক্রিপ্ট স্পেস্কে কোথাও নেই।
জো মাফি

-2

আপনার স্ট্রিংগুলি rapেকে রাখুন / /i। কেসিং উপেক্ষা করার জন্য এটি রেজেেক্স ব্যবহার করার একটি সহজ উপায়


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