জাভাস্ক্রিপ্ট: বর্ণানুক্রমিক স্ট্রিং প্রাকৃতিক সাজান


173

সংখ্যা এবং পাঠ্য এবং এগুলির সংমিশ্রণযুক্ত একটি অ্যারে বাছাই করার সহজতম উপায় আমি সন্ধান করছি।

যেমন

'123asd'
'19asd'
'12345asd'
'asd123'
'asd12'

পরিণত হয়

'19asd'
'123asd'
'12345asd'
'asd12'
'asd123'

আমি এখানে জিজ্ঞাসা করেছি এমন আরও একটি প্রশ্নের সমাধানের সাথে এটি একত্রে ব্যবহৃত হতে চলেছে ।

বাছাইকরণ ফাংশনটি নিজেই কাজ করে, আমার যা প্রয়োজন তা হল একটি ফাংশন যা বলতে পারে যে '19asd' '123asd' এর চেয়ে ছোট।

আমি জাভাস্ক্রিপ্ট এ লিখছি।

সম্পাদনা: অ্যাডর্মিটু যেমন বলেছিল , আমি যা খুঁজছি তা হল প্রাকৃতিক বাছাইয়ের জন্য একটি ফাংশন


আরো দেখুন How do you do string comparison in JavaScript?উপর stackoverflow.com/questions/51165/...
Adrien হউন

1
আসল প্রশ্নটি 2010 সালে জিজ্ঞাসা করা হয়েছিল, তাই অবাক হওয়ার মতো কিছু হবে না :)
ptrn

উত্তর:


316

স্থানীয় ব্রাউজারে লোকালকম্পার ব্যবহার করে এটি এখন সম্ভব। numeric: trueবিকল্পটি পাস করার মাধ্যমে , এটি স্মার্টভাবে নম্বরগুলি সনাক্ত করবে। আপনি কেস-সংবেদনশীল ব্যবহার করে করতে পারেন sensitivity: 'base'। ক্রোম, ফায়ারফক্স এবং আই 11 এ পরীক্ষিত।

এখানে একটি উদাহরণ। এটি ফিরে আসে 1, যার অর্থ 10 পরে 2:

'10'.localeCompare('2', undefined, {numeric: true, sensitivity: 'base'})

বিপুল সংখ্যক স্ট্রিং বাছাই করার সময় পারফরম্যান্সের জন্য, নিবন্ধটি বলে:

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

var collator = new Intl.Collator(undefined, {numeric: true, sensitivity: 'base'});
var myArray = ['1_Document', '11_Document', '2_Document'];
console.log(myArray.sort(collator.compare));


12
আপনি যদি কোনও বস্তুর অ্যারে বাছাই করতে চান তবে আপনি কল্টারটিও ব্যবহার করতে পারেন: কোডেপেন.ইও
টিমপাইট্রস্কি /

2
উপরের মন্তব্যটি স্পষ্ট করতে: "যদি লোকেল আর্গুমেন্ট সরবরাহ করা হয় বা অপরিজ্ঞাত না করা হয়, রানটাইমের ডিফল্ট লোকেল ব্যবহৃত হয়।"
gkiely

46

সুতরাং আপনি একটি প্রাকৃতিক বাছাই প্রয়োজন ?

যদি তা হয় তবে ডেভিড কোয়েলের কাজের উপর ভিত্তি করে ব্রায়ান হুইসমানের এই স্ক্রিপ্টটি আপনার যা প্রয়োজন তা হ'ল

দেখে মনে হচ্ছে ব্রায়ান হুইসমানের সমাধানটি এখন সরাসরি ডেভিড কোয়েলের ব্লগে হোস্ট করা হয়েছে:


সঠিক, প্রাকৃতিক বাছাই আমি যা খুঁজছি looking আপনি প্রেরিত লিঙ্কটি আমি সন্ধান করব, ধন্যবাদ
ptrn

এটি খুব অপ্রাকৃত। এটি কোনও বর্ণমালা বাছাই করে না।
tchrist

@ ক্রিশ্চট: "এটি বর্ণমালা বাছাই করে না?" বলতে কী বোঝ?
অ্যাড্রিয়েন

এটি দুর্দান্ত কাজ করে তবে এটি নেতিবাচক সংখ্যাগুলি সঠিকভাবে পরিচালনা করে না। অর্থাৎ: এটি ['-1' উত্পাদন করবে। '-2', '0', '1', '2']।
অ্যাড্রিয়ানবাইমভাইজার

2
@mhitza এই কোডটি ভাল কাজ করছে বলে মনে হচ্ছে github.com/litejs/n Natural
অ্যাড্রিয়েন ২ Be

23

মানগুলির তুলনা করতে আপনি একটি তুলনা পদ্ধতি ব্যবহার করতে পারেন-

function naturalSorter(as, bs){
    var a, b, a1, b1, i= 0, n, L,
    rx=/(\.\d+)|(\d+(\.\d+)?)|([^\d.]+)|(\.\D+)|(\.$)/g;
    if(as=== bs) return 0;
    a= as.toLowerCase().match(rx);
    b= bs.toLowerCase().match(rx);
    L= a.length;
    while(i<L){
        if(!b[i]) return 1;
        a1= a[i],
        b1= b[i++];
        if(a1!== b1){
            n= a1-b1;
            if(!isNaN(n)) return n;
            return a1>b1? 1:-1;
        }
    }
    return b[i]? -1:0;
}

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

function naturalSort(ar, index){
    var L= ar.length, i, who, next, 
    isi= typeof index== 'number', 
    rx=  /(\.\d+)|(\d+(\.\d+)?)|([^\d.]+)|(\.(\D+|$))/g;
    function nSort(aa, bb){
        var a= aa[0], b= bb[0], a1, b1, i= 0, n, L= a.length;
        while(i<L){
            if(!b[i]) return 1;
            a1= a[i];
            b1= b[i++];
            if(a1!== b1){
                n= a1-b1;
                if(!isNaN(n)) return n;
                return a1>b1? 1: -1;
            }
        }
        return b[i]!= undefined? -1: 0;
    }
    for(i= 0; i<L; i++){
        who= ar[i];
        next= isi? ar[i][index] || '': who;
        ar[i]= [String(next).toLowerCase().match(rx), who];
    }
    ar.sort(nSort);
    for(i= 0; i<L; i++){
        ar[i]= ar[i][1];
    }
}

এটি কি আমার ক্ষেত্রে, অভ্যন্তরীণ অ্যারেটি বাইরেরটির ক্রমটি স্থির করে?
পিটিএনএন

কি String.prototype.tlc()? এটি কি আপনার নিজস্ব কোড না আপনি কোথাও থেকে পেয়েছেন? যদি পরে থাকে তবে দয়া করে পৃষ্ঠায় লিঙ্ক করুন।
অ্যান্ডি ই

ভুল সম্পর্কে দুঃখিত - সংশোধন, আপনাকে ধন্যবাদ। আপনি যদি একটি [1] এবং খ [1] বাছাই করতে চান তবে a = স্ট্রিং (একটি [1]) ব্যবহার করুন toলওওয়ারকেস (); বি = স্ট্রিং (খ [1])। টু লোয়ারকেস ();
কেনেবেক

আমার কাছে কেবলমাত্র ডেটাগুলির একটি তালিকা ছিল যা আমি বাছাই করতে চেয়েছিলাম, ভেবেছিলাম ক্রোম দেব সরঞ্জামগুলির কনসোলটিতে এটি করা সহজ হওয়া উচিত - ফাংশনের জন্য ধন্যবাদ!
ajh158

9

আপনার যদি অবজেক্টগুলির একটি অ্যারে থাকে তবে আপনি এটি করতে পারেন:

myArrayObjects = myArrayObjects.sort(function(a, b) {
  return a.name.localeCompare(b.name, undefined, {
    numeric: true,
    sensitivity: 'base'
  });
});


1
নিখুঁত উত্তর! ধন্যবাদ.
hubert17

5

2019 পর্যন্ত এটি হ্যান্ডেল করার জন্য সর্বাধিক বৈশিষ্ট্যযুক্ত লাইব্রেরিটি প্রাকৃতিক-অর্ডবাই বলে মনে হচ্ছে ।

const { orderBy } = require('natural-orderby')

const unordered = [
  '123asd',
  '19asd',
  '12345asd',
  'asd123',
  'asd12'
]

const ordered = orderBy(unordered)

// [ '19asd',
//   '123asd',
//   '12345asd',
//   'asd12',
//   'asd123' ]

এটি কেবল স্ট্রিংগুলির অ্যারে নেয় না, তবে বস্তুর অ্যারেতে একটি নির্দিষ্ট কী এর মান অনুসারে বাছাই করতে পারে। এটি স্বয়ংক্রিয়ভাবে এর স্ট্রিংগুলি সনাক্ত করে বাছাই করতে পারে: মুদ্রা, তারিখ, মুদ্রা এবং অন্যান্য কিছু জিনিস।

আশ্চর্যের বিষয়, জিজেপ করা অবস্থায় এটি কেবল 1.6kB।


2

রূপান্তর করে এমন একটি 8 ডিজিটের প্যাডিং ফাংশনটি কল্পনা করুন:

  • '123asd' -> '00000123asd'
  • '19asd' -> '00000019asd'

'123 এসএসডি' এর আগে উপস্থিত হতে 19 19sd সাজানোর জন্য আমরা প্যাডযুক্ত স্ট্রিংগুলি ব্যবহার করতে পারি।

/\d+/gপ্যাড করা দরকার এমন সমস্ত নম্বর খুঁজে পেতে নিয়মিত প্রকাশটি ব্যবহার করুন :

str.replace(/\d+/g, pad)

নিম্নলিখিতটি এই কৌশলটি ব্যবহার করে বাছাই করে দেখায়:

var list = [
    '123asd',
    '19asd',
    '12345asd',
    'asd123',
    'asd12'
];

function pad(n) { return ("00000000" + n).substr(-8); }
function natural_expand(a) { return a.replace(/\d+/g, pad) };
function natural_compare(a, b) {
    return natural_expand(a).localeCompare(natural_expand(b));
}

console.log(list.map(natural_expand).sort()); // intermediate values
console.log(list.sort(natural_compare)); // result

মধ্যবর্তী ফলাফলগুলি প্রাকৃতিক_পরিষ্কার () রুটিনটি কী করে তা আপনাকে দেখায় এবং পরবর্তী প্রাকৃতিক_কামনা রুটিন কীভাবে কাজ করবে তা আপনাকে বোঝায়:

[
  "00000019asd",
  "00000123asd",
  "00012345asd",
  "asd00000012",
  "asd00000123"
]

আউটপুট:

[
  "19asd",
  "123asd",
  "12345asd",
  "asd12",
  "asd123"
]

1

উপরে @ অ্যাড্রিয়েন বি এর উত্তর তৈরি করা এবং ব্রায়ান হুইসমান এবং ডেভিড কোয়েল যে কোডটি তৈরি করেছে তা ব্যবহার করে , এখানে অবজেক্টগুলির অ্যারের জন্য একটি পরিবর্তিত প্রোটোটাইপ বাছাই করা হল:

//Usage: unsortedArrayOfObjects.alphaNumObjectSort("name");
//Test Case: var unsortedArrayOfObjects = [{name: "a1"}, {name: "a2"}, {name: "a3"}, {name: "a10"}, {name: "a5"}, {name: "a13"}, {name: "a20"}, {name: "a8"}, {name: "8b7uaf5q11"}];
//Sorted: [{name: "8b7uaf5q11"}, {name: "a1"}, {name: "a2"}, {name: "a3"}, {name: "a5"}, {name: "a8"}, {name: "a10"}, {name: "a13"}, {name: "a20"}]

// **Sorts in place**
Array.prototype.alphaNumObjectSort = function(attribute, caseInsensitive) {
  for (var z = 0, t; t = this[z]; z++) {
    this[z].sortArray = new Array();
    var x = 0, y = -1, n = 0, i, j;

    while (i = (j = t[attribute].charAt(x++)).charCodeAt(0)) {
      var m = (i == 46 || (i >=48 && i <= 57));
      if (m !== n) {
        this[z].sortArray[++y] = "";
        n = m;
      }
      this[z].sortArray[y] += j;
    }
  }

  this.sort(function(a, b) {
    for (var x = 0, aa, bb; (aa = a.sortArray[x]) && (bb = b.sortArray[x]); x++) {
      if (caseInsensitive) {
        aa = aa.toLowerCase();
        bb = bb.toLowerCase();
      }
      if (aa !== bb) {
        var c = Number(aa), d = Number(bb);
        if (c == aa && d == bb) {
          return c - d;
        } else {
          return (aa > bb) ? 1 : -1;
        }
      }
    }

    return a.sortArray.length - b.sortArray.length;
  });

  for (var z = 0; z < this.length; z++) {
    // Here we're deleting the unused "sortArray" instead of joining the string parts
    delete this[z]["sortArray"];
  }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.