জাভাস্ক্রিপ্টে স্ট্রিংগুলি কীভাবে সাজানো যায়


344

attrটাইপ স্ট্রিংয়ের ক্ষেত্রের উপর ভিত্তি করে আমার সাজানো ইস্যুগুলির একটি তালিকা রয়েছে । আমি ব্যবহার করার চেষ্টা করেছি-

list.sort(function (a, b) {
    return a.attr - b.attr
})

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



দ্রুত "আন্তর্জাতিকীকরণ" সমাধানের জন্য (কেবলমাত্র আংশিকভাবে আমি অনুমান করি যেহেতু এটি বিশ্বের সমস্ত অ্যাকসেন্টকে কভার করতে পারে না), আপনি কেবল উচ্চারণগুলিকে উপেক্ষা করতে চাইতে পারেন, এগুলি সরাতে। তারপরে কেবল আপনার স্ট্রিং তুলনা করুন, স্ট্যাকওভারফ্লোJavascript : remove accents/diacritics in strings . com
অ্যাড্রিয়েন

2
2007 সালে জেফ আতউড নিজেই এই সাধারণ সমস্যাটি সম্পর্কে একটি ব্লগ পোস্ট লিখেছিলেন, মজাদার পর্যায়ে দেখুন, ব্লগকোডিংহরর.com
অ্যাড্রিয়েন

উত্তর:


620

String.prototype.localeCompareআপনার উদাহরণ প্রতি একটি ব্যবহার করুন :

list.sort(function (a, b) {
    return ('' + a.attr).localeCompare(b.attr);
})

ব্যতিক্রমগুলি এড়ানোর জন্য আমরা a.attr কে স্ট্রিং হিসাবে বাধ্য করি। ইন্টারনেট এক্সপ্লোরার 6 এবং ফায়ারফক্স ১-এর পরlocaleCompare থেকে সমর্থন করা হয়েছে আপনি নীচের কোডটিও ব্যবহার করতে পারেন যা কোনও লোকেলের সম্মান করে না:

if (item1.attr < item2.attr)
  return -1;
if ( item1.attr > item2.attr)
  return 1;
return 0;

81
আমার মতো যে কেউ তাড়াহুড়ো করে ভুল করার আগে এটি স্থানীয় এবং তুলনা করুন, স্থানীয় তুলনা করুন না।
এপ্টেম্বর

12
প্রথম সমাধান "জ" এর পরে আসার জন্য "এ" বিবেচনা করবে তবে "জেড" এর আগে এটি ASCII চরিত্রটির তুলনা করছে। localeCompare()এই সমস্যার মধ্যে চলে না তবে সংখ্যাগুলি বোঝে না তাই আপনি বেশিরভাগ ভাষায় তুলনা বাছাই করার সাথে সাথে ["1", "10", "2"] পাবেন। আপনি আপনার ইউআই সামনে শেষ জন্য বাছাই চান, alphanum / প্রাকৃতিক সাজানোর আলগোরিদিম দেখব stackoverflow.com/questions/4340227/... বা stackoverflow.com/questions/4321829/...
Dead.Rabit

2
নোট যেটি localeCompare()শুধুমাত্র আধুনিক ব্রাউজারগুলিতে সমর্থিত: আইই 11 + লেখার সময়, বিকাশকারী.মোজিলা.আর.ইন.ইউএস
অ্যাড্রিয়েন

3
না, আমি টেবিলের প্রথম লাইনটি বুঝি, @ অ্যাড্রিয়েন - আইই localeCompare()অনেকগুলি সংস্করণ ফিরে পেতে সমর্থন করে তবে সংস্করণ ১১ পর্যন্ত স্থানীয় নির্দিষ্টকরণ সমর্থন করে না , মৃত.রবিট যে প্রশ্নগুলির সাথে লিঙ্ক করেছেন সেগুলিও নোট করুন।
শোগ 9

3
@ শোগ 9 আমার খারাপ, দেখে মনে হচ্ছে এটি আইআই 6 এর পরে সমর্থিত! দেখেন (স্ক্রল ডাউন / localeCompare () মেথড করার জন্য অনুসন্ধান) msdn.microsoft.com/en-us/library/ie/s4esdbwz(v=vs.94).aspx । তবে একটি বিষয় লক্ষণীয়, পুরাতন বাস্তবায়নে যেখানে আমরা লোকেল এবং বিকল্পের আর্গুমেন্টগুলি ব্যবহার করি না (IE11 এর আগে ব্যবহৃত একটি) ব্যবহৃত লোকেল এবং সাজানোর ক্রমটি সম্পূর্ণ বাস্তবায়ন নির্ভর করে , অন্য কথায়: ফায়ারফক্স, সাফারি, ক্রোম এবং আইই একই ক্রমে স্ট্রিংগুলি সাজান না। কোড. google.com/p/v8/issues/detail?id=459 দেখুন
অ্যাড্রিয়েন

166

একটি আপডেট উত্তর (অক্টোবর 2014)

আমি এই স্ট্রিং প্রাকৃতিক বাছাইয়ের আদেশ সম্পর্কে সত্যিই বিরক্ত হয়েছিলাম তাই এই সমস্যাটি তদন্ত করতে বেশ কিছুটা সময় নিয়েছিলাম। আশা করি এটা কাজে লাগবে.

দীর্ঘ সংক্ষিপ্ত বিবরণ

localeCompare()চরিত্র সমর্থন খারাপ, কেবল এটি ব্যবহার করুন। যেমন নির্দেশিত হয়েছে Shog9, আপনার প্রশ্নের উত্তরটি হ'ল:

return item1.attr.localeCompare(item2.attr);

সমস্ত কাস্টম জাভাস্ক্রিপ্ট "প্রাকৃতিক স্ট্রিং সাজানোর আদেশ" বাস্তবায়নগুলিতে পাওয়া গেছে found

স্ট্রিং তুলনা আরও বেশি স্পষ্টভাবে "প্রাকৃতিক স্ট্রিং সাজানোর ক্রম" বলা করার চেষ্টা করার চেষ্টা করছে সেখানে প্রচুর কাস্টম বাস্তবায়ন হয়েছে out

এই বাস্তবায়নগুলির সাথে "খেলতে", আমি সর্বদা কিছু অদ্ভুত "প্রাকৃতিক বাছাইয়ের আদেশ" পছন্দ, বা বরং ভুলগুলি (বা সেরা ক্ষেত্রে বাদ দেওয়া) লক্ষ্য করেছি।

সাধারণত, বিশেষ অক্ষর (স্পেস, ড্যাশ, অ্যাম্পারস্যান্ড, বন্ধনী এবং তাই) সঠিকভাবে প্রক্রিয়া করা হয় না।

তারপরে আপনি এগুলিকে বিভিন্ন স্থানে মিশে যেতে দেখবেন, সাধারণত এটি হতে পারে:

  • কিছু বড় হাতের 'জেড' এবং ছোট হাতের 'এ' এর মধ্যে থাকবে
  • কিছু '9' এবং বড় হাতের 'এ' এর মধ্যে থাকবে
  • কিছু ছোট হাতের জেড পরে হবে

স্পেস স্পেশাল চরিত্রটি বাদে (যখন সর্বদা প্রথম চরিত্রটি হবে) ব্যতীত যখন কেউ বিশেষ অক্ষরগুলি এক জায়গায় একসাথে "দলবদ্ধ" হওয়ার আশা করত। এটি হ'ল হয় সংখ্যার আগে সমস্ত, বা সমস্ত সংখ্যা এবং অক্ষরের মধ্যে (ছোট হাতের অক্ষর এবং বড় হাতের একের পর এক "একসাথে"), বা সমস্ত অক্ষরের পরে।

আমার উপসংহারটি হ'ল যখন আমি সবেমাত্র অস্বাভাবিক চরিত্রগুলি (যেমন ডায়াস্রিটিকস বা চার্টারস যেমন ড্যাশ, বিস্মৃত চিহ্ন এবং আরও কিছু দিয়ে অক্ষরগুলি) যুক্ত করা শুরু করি তখন তারা সকলেই একটি সামঞ্জস্যপূর্ণ অর্ডার সরবরাহ করতে ব্যর্থ হয়।

কাস্টম বাস্তবায়ন সম্পর্কিত গবেষণা:

এর মাধ্যমে ব্রাউজারগুলির স্থানীয় "প্রাকৃতিক স্ট্রিং সাজানোর ক্রম" প্রয়োগকরণ localeCompare()

localeCompare()পুরানো বাস্তবায়ন (স্থানীয় এবং বিকল্পের আর্গুমেন্ট ব্যতীত) আই 6+ দ্বারা সমর্থিত, দেখুন http://msdn.microsoft.com/en-us/library/ie/s4esdbwz(vvv.9.94).aspx (লোকালকম্পারে স্ক্রোল করুন ( ) পদ্ধতি)। অন্তর্নির্মিত localeCompare()পদ্ধতিটি বাছাইয়ের ক্ষেত্রে এমনকি আন্তর্জাতিক এবং বিশেষ চরিত্রগুলিতে আরও ভাল কাজ করে। localeCompare()পদ্ধতিটি ব্যবহার করে শুধুমাত্র সমস্যাটি হ'ল "ব্যবহৃত লোকেল এবং সাজানোর ক্রমটি সম্পূর্ণ বাস্তবায়ন নির্ভর" " অন্য কথায়, লোকালকম্পার যেমন স্ট্রিংওনে.লোকেলকম্পার (স্ট্রিংটো) ব্যবহার করার সময়: ফায়ারফক্স, সাফারি, ক্রোম এবং আই স্ট্রিংয়ের জন্য আলাদা ধরণের ক্রম রয়েছে।

ব্রাউজার-নেটিভ বাস্তবায়নের উপর গবেষণা:

"স্ট্রিং প্রাকৃতিক বাছাইয়ের আদেশ" এর অসুবিধা

একটি দৃ al় অ্যালগরিদম বাস্তবায়ন (যার অর্থ: ধারাবাহিক তবে বিস্তৃত চরিত্রগুলিও coveringেকে দেওয়া) একটি খুব শক্ত কাজ। ইউটিএফ 8 এ 2000 টিরও বেশি অক্ষর রয়েছে এবং এতে 120 টিরও বেশি স্ক্রিপ্ট (ভাষা) রয়েছে । অবশেষে, এই কাজের জন্য কিছু স্পেসিফিকেশন রয়েছে, একে "ইউনিকোড কলেশন অ্যালগরিদম" বলা হয়, এটি http://www.unicode.org/report/tr10/ এ পাওয়া যাবে । আপনি এই প্রশ্নে এই সম্পর্কিত আরও তথ্য পেতে পারেন আমি পোস্ট করেছি /software/257286/is-there-any-language-agnostic-specifications-for-string-n Natural- sorting-order

চূড়ান্ত উপসংহার

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

সুতরাং দ্বারা নির্দেশিত হিসাবে Shog9, আপনার প্রশ্নের উত্তর হ'ল:

return item1.attr.localeCompare(item2.attr);

আরও পড়া:

শোগ 9-এর দুর্দান্ত উত্তরের জন্য ধন্যবাদ, যেটি আমাকে বিশ্বাস করে "সঠিক" দিকে নিয়ে যায়


38

উত্তর (আধুনিক ECMAScript এ)

list.sort((a, b) => (a.attr > b.attr) - (a.attr < b.attr))

অথবা

list.sort((a, b) => +(a.attr > b.attr) || -(a.attr < b.attr))

বিবরণ

একটি সংখ্যাতে একটি বুলিয়ান মান কাস্ট করা নিম্নলিখিত ফলন করে:

  • true -> 1
  • false -> 0

তিনটি সম্ভাব্য নিদর্শন বিবেচনা করুন:

  • x y এর চেয়ে বড়: (x > y) - (y < x)-> 1 - 0->1
  • x এর সমান y: (x > y) - (y < x)-> 0 - 0->0
  • x y এর চেয়ে ছোট: (x > y) - (y < x)-> 0 - 1->-1

(বিকল্প)

  • x y এর চেয়ে বড়: +(x > y) || -(x < y)-> 1 || 0->1
  • x এর সমান y: +(x > y) || -(x < y)-> 0 || 0->0
  • x y এর চেয়ে ছোট: +(x > y) || -(x < y)-> 0 || -1->-1

সুতরাং এই লজিকগুলি সাধারণ সাজানোর তুলনামূলক ফাংশনের সমতুল্য।

if (x == y) {
    return 0;
}
return x > y ? 1 : -1;

1
আমি এই কৌশলটি ব্যবহার করে এমন পূর্বের উত্তরের বিষয়ে যেমন মন্তব্য করেছি , কোড-উত্তরগুলি তারা কীভাবে কাজ করে তা ব্যাখ্যা করে আরও দরকারী করা যেতে পারে।
ড্যান ড্যাসক্লেস্কু

বিবরণ যুক্ত করা হয়েছে
এমপিইউ

এটি লোকেলকম্পারের চেয়ে ভাল বা খারাপ এটি সম্পর্কে আপনি মন্তব্য করতে পারেন?
রণ লোটোমে

3
@ রনলোটম localeCompareএবং মান তুলনা বিভিন্ন ফলাফল দেয়। আপনি কোনটি আশা করেন? ["A", "b", "C", "d"].sort((a, b) => a.localeCompare(b))["A", "b", "C", "d"].sort((a, b) => (a > b) - (a < b))
কোডেপয়েন্টে

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

13

আপনার এখানে> বা <এবং == ব্যবহার করা উচিত। সুতরাং সমাধানটি হ'ল:

list.sort(function(item1, item2) {
    var val1 = item1.attr,
        val2 = item2.attr;
    if (val1 == val2) return 0;
    if (val1 > val2) return 1;
    if (val1 < val2) return -1;
});

1
পার্শ্ব নোটে, এটি স্ট্রিং বনাম সংখ্যা তুলনা পরিচালনা করবে না। উদাহরণস্বরূপ: 'জেড' <9 (মিথ্যা), 'জেড'> 9 (এছাড়াও মিথ্যা ??), 'জেড' == 9 (এছাড়াও মিথ্যা !!)। জাভাস্ক্রিপ্টে মূর্খ NaN ...
কটো

7

নেস্টেড টেরেনারি অ্যার ফাংশন

(a,b) => (a < b ? -1 : a > b ? 1 : 0)

7

যেহেতু স্ট্রিংগুলি সরাসরি জাভাস্ক্রিপ্টের সাথে তুলনা করা যায়, এটি কাজটি করবে

list.sort(function (a, b) {
    return a.attr > b.attr ? 1: -1;
})

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


6

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

অনুমান থেকে :

Section 11.9.4   The Strict Equals Operator ( === )

The production EqualityExpression : EqualityExpression === RelationalExpression
is evaluated as follows: 
- Let lref be the result of evaluating EqualityExpression.
- Let lval be GetValue(lref).
- Let rref be the result of evaluating RelationalExpression.
- Let rval be GetValue(rref).
- Return the result of performing the strict equality comparison 
  rval === lval. (See 11.9.6)

সুতরাং এখন আমরা 11.9.6 এ চলেছি

11.9.6   The Strict Equality Comparison Algorithm

The comparison x === y, where x and y are values, produces true or false. 
Such a comparison is performed as follows: 
- If Type(x) is different from Type(y), return false.
- If Type(x) is Undefined, return true.
- If Type(x) is Null, return true.
- If Type(x) is Number, then
...
- If Type(x) is String, then return true if x and y are exactly the 
  same sequence of characters (same length and same characters in 
  corresponding positions); otherwise, return false.

এটাই. স্ট্রিংগুলিতে প্রয়োগ করা ট্রিপল ইক্যুয়াল অপারেটর সত্যটি প্রদান করে যদি আর্গুমেন্টগুলি একই স্ট্রিং হয় (একই অবস্থানের ক্ষেত্রে একই দৈর্ঘ্য এবং একই অক্ষর)।

তাই ===মামলা যখন আমরা স্ট্রিং বিভিন্ন সূত্র থেকে এসেছে হতে পারে তুলনা করার চেষ্টা করছেন কাজ করবে, কিন্তু আমরা জানি যা অবশেষে একই মান ধারণ করবে - আমাদের কোডে ইনলাইন স্ট্রিং জন্য একটি সাধারণ যথেষ্ট দৃশ্যকল্প। উদাহরণস্বরূপ, যদি আমাদের একটি ভেরিয়েবলের নাম দেওয়া থাকে connection_stateএবং আমরা ['connecting', 'connected', 'disconnecting', 'disconnected']এখনই নীচের কোনটি রাজ্যের এটি জানতে চাই, আমরা সরাসরি এটি ব্যবহার করতে পারি ===

তবে আরও কিছু আছে। ১১.৯.৪ এর ঠিক উপরে, একটি সংক্ষিপ্ত নোট রয়েছে:

NOTE 4     
  Comparison of Strings uses a simple equality test on sequences of code 
  unit values. There is no attempt to use the more complex, semantically oriented
  definitions of character or string equality and collating order defined in the 
  Unicode specification. Therefore Strings values that are canonically equal
  according to the Unicode standard could test as unequal. In effect this 
  algorithm assumes that both Strings are already in normalized form.

হুম। এখন কি? বাহ্যিকভাবে প্রাপ্ত স্ট্রিংগুলি অদ্ভুত ইউনিকোডি হতে পারে এবং আমাদের সৌম্য ===তাদের ন্যায়বিচার করতে পারে না। localeCompareউদ্ধার করতে আসে :

15.5.4.9   String.prototype.localeCompare (that)
    ...
    The actual return values are implementation-defined to permit implementers 
    to encode additional information in the value, but the function is required 
    to define a total ordering on all Strings and to return 0 when comparing
    Strings that are considered canonically equivalent by the Unicode standard. 

আমরা এখন বাড়িতে যেতে পারি

TL; ড;

জাভাস্ক্রিপ্টে স্ট্রিংগুলির তুলনা করতে, ব্যবহার করুন localeCompare; যদি আপনি জানেন যে স্ট্রিংগুলির কোনও অ-এসসিআইআই উপাদান নেই কারণ সেগুলি উদাহরণস্বরূপ, অভ্যন্তরীণ প্রোগ্রামের ধ্রুবকগুলির পরে ===কাজ করে।


0

আপনার প্রাথমিক প্রশ্নে আপনার অপারেশনে, আপনি নিম্নলিখিত অপারেশনটি সম্পাদন করছেন:

item1.attr - item2.attr

সুতরাং, ধরে নিলে সেগুলি সংখ্যা (যেমন আইটেম 1.attr = "1", আইটেম 2.attr = "2") আপনি এখনও "===" অপারেটর (বা অন্যান্য কঠোর মূল্যায়নকারী) ব্যবহার করতে পারেন যে আপনি প্রকারটি নিশ্চিত করেছেন। নিম্নলিখিত কাজ করা উচিত:

return parseInt(item1.attr) - parseInt(item2.attr);

সেগুলি যদি আলফা সংখ্যাসূচক হয় তবে লোকালকম্পার () ব্যবহার করুন।


0
list.sort(function(item1, item2){
    return +(item1.attr > item2.attr) || +(item1.attr === item2.attr) - 1;
}) 

তারা কীভাবে নমুনাগুলি কাজ করে:

+('aaa'>'bbb')||+('aaa'==='bbb')-1
+(false)||+(false)-1
0||0-1
-1

+('bbb'>'aaa')||+('bbb'==='aaa')-1
+(true)||+(false)-1
1||0-1
1

+('aaa'>'aaa')||+('aaa'==='aaa')-1
+(false)||+(true)-1
0||1-1
0

3
কেবল কোডের উত্তরগুলি কীভাবে কাজ করে তা ব্যাখ্যা করে আরও দরকারী করা যায় can
ড্যান ড্যাসকলেস্কু

-2
<!doctype html>
<html>
<body>
<p id = "myString">zyxtspqnmdba</p>
<p id = "orderedString"></p>
<script>
var myString = document.getElementById("myString").innerHTML;
orderString(myString);
function orderString(str) {
    var i = 0;
    var myArray = str.split("");
    while (i < str.length){
        var j = i + 1;
        while (j < str.length) {
            if (myArray[j] < myArray[i]){
                var temp = myArray[i];
                myArray[i] = myArray[j];
                myArray[j] = temp;
            }
            j++;
        }
        i++;
    }
    var newString = myArray.join("");
    document.getElementById("orderedString").innerHTML = newString;
}
</script>
</body>
</html>

1
এটি আপনার উত্তরটিতে কীভাবে প্রশ্নটির সমাধান করতে চলেছে তাতে কিছু ইনফস যুক্ত করুন। কেবলমাত্র কোডের উত্তরগুলি স্বাগত জানানো হয় না। ধন্যবাদ.
WayneOS

এখানে আপনি একটি স্ট্রিংয়ের মধ্যে অক্ষরগুলি অর্ডার করতে চান, যা জিজ্ঞাসা করা হয় তা নয়। আপনি "Array.sort" যেমন str.split ( "")। সাজানোর () .join ( "") ব্যবহার করে এই কেবল বাছাই অর্জন করতে পারেন
Alejadro Xalabarder

-2
var str = ['v','a','da','c','k','l']
var b = str.join('').split('').sort().reverse().join('')
console.log(b)

এই কোডটি কীভাবে এবং কেন এই সমস্যার সমাধান করে তার একটি ব্যাখ্যা সহ প্রশ্নটি সমাধান করতে পারে যদিও আপনার পোস্টের গুণমান উন্নত করতে সত্যই সহায়তা করবে এবং সম্ভবত আরও বেশি ভোটের ফলাফল হবে। মনে রাখবেন যে আপনি ভবিষ্যতে পাঠকদের জন্য প্রশ্নের উত্তর দিচ্ছেন, কেবল এখনই জিজ্ঞাসা করা ব্যক্তি নয়। দয়া করে ব্যাখ্যা যুক্ত করতে আপনার উত্তর সম্পাদনা করুন, এবং কোন সীমাবদ্ধতা এবং অনুমানগুলি প্রযোজ্য তা একটি ইঙ্গিত দিন।
ডেভ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.