জাভাস্ক্রিপ্টে এর মান অনুসারে কোনও এসোসিয়েটিভ অ্যারে কীভাবে বাছাই করবেন?


84

আমার কাছে সহযোগী অ্যারে রয়েছে:

array["sub2"] = 1;
array["sub0"] = -1;
array["sub1"] = 0;
array["sub3"] = 1;
array["sub4"] = 0;

এর মান অনুসারে বাছাইয়ের (উতরোত্তর) সর্বাধিক মার্জিত উপায় কী যেখানে ফলাফলটি এই ক্রমে সম্পর্কিত সূচকগুলির সাথে একটি অ্যারে হবে:

sub2, sub3, sub1, sub4, sub0

4
যেহেতু বস্তুর বৈশিষ্ট্যগুলির কোনও ভাষা নির্ধারিত অর্ডার নেই - আপনি কিছু জেএস ইঞ্জিনে নির্দিষ্ট বৈশিষ্ট্যের উপর নির্ভর করে যে তারা বৈশিষ্ট্যগুলি বাস্তবায়িত করে তা করতে পারবেন না।
কুইন্টিন

উত্তর:


115

জাভাস্ক্রিপ্টে আপনি যেভাবে ভাবছেন সেভাবে "সহযোগী অ্যারে" নেই। পরিবর্তে, আপনার কাছে কেবল অ্যারের মতো বাক্য গঠন (যেমন আপনার উদাহরণ হিসাবে) ব্যবহার করে অবজেক্টের বৈশিষ্ট্য সেট করার ক্ষমতা রয়েছে, পাশাপাশি কোনও বস্তুর বৈশিষ্ট্যগুলি নিয়ে পুনরাবৃত্তি করার ক্ষমতাও রয়েছে।

এই পরিণতি হিসেবে কোন গ্যারান্টি নেই যে অর্ডার যা আপনি পুনরুক্তি বৈশিষ্ট্য উপর, তাই তাদের জন্য একটি সাজানোর মত কিছুই নেই। পরিবর্তে, আপনাকে আপনার অবজেক্ট বৈশিষ্ট্যগুলিকে "সত্য" অ্যারে রূপান্তর করতে হবে (যা গ্যারান্টি অর্ডার দেয়)। কোনও জিনিসকে দ্বি-টিপলস (দ্বি-উপাদান অ্যারে) এর অ্যারে রূপান্তর করার জন্য এখানে একটি কোড স্নিপেট, আপনার বর্ণনা অনুসারে বাছাই করুন, তারপরে পুনরাবৃত্তি করুন:

var tuples = [];

for (var key in obj) tuples.push([key, obj[key]]);

tuples.sort(function(a, b) {
    a = a[1];
    b = b[1];

    return a < b ? -1 : (a > b ? 1 : 0);
});

for (var i = 0; i < tuples.length; i++) {
    var key = tuples[i][0];
    var value = tuples[i][1];

    // do something with key and value
}

আপনি একটি ফাংশন যা কলব্যাক লাগে এটি মোড়ানো আরও প্রাকৃতিক হতে পারে:

function bySortedValue(obj, callback, context) {
  var tuples = [];

  for (var key in obj) tuples.push([key, obj[key]]);

  tuples.sort(function(a, b) {
    return a[1] < b[1] ? 1 : a[1] > b[1] ? -1 : 0
  });

  var length = tuples.length;
  while (length--) callback.call(context, tuples[length][0], tuples[length][1]);
}

bySortedValue({
  foo: 1,
  bar: 7,
  baz: 3
}, function(key, value) {
  document.getElementById('res').innerHTML += `${key}: ${value}<br>`
});
<p id='res'>Result:<br/><br/><p>


4
tuples.sort ফাংশনটি tuples.sort পর্যন্ত পরিষ্কার করা যায় (ফাংশন (ক, খ) {ফিরে আসুন [1] - খ [1]; {);
stot

4
@ স্টট - যদি আপনার মানগুলি সমস্ত সংখ্যার হয় (যেমন প্রশ্নকারীর উদাহরণ হিসাবে), একেবারে। আমি উপস্থিত থেকে অনুপস্থিত-মনের সাথে একটি তুলনা ফাংশন সরবরাহ করেছি যা স্ট্রিংগুলির সাথেও কাজ করে। :-)
বেন ফাঁকা

@ বেন: হ্যাঁ আপনি ঠিক বলেছেন, সরবরাহিত সংস্করণটি আরও সাধারণ ;-)
স্টট

@ বেন, এই পোস্টের জন্য আপনাকে অনেক ধন্যবাদ। স্ট্রিং তুলনা ফাংশন সম্পর্কিত, এটি কোনও ASCII মান তুলনা ব্যবহার করে?
jjwdesign

@jjwdesign, ধরে নিলাম স্ট্রিংটি এনকোড করা হয়নি, এটি ইউনিকোড কোড পয়েন্ট অনুসারে বাছাই করবে।
বেন ফাঁকা

86

আপনাকে 'এসোসিয়েটিভ অ্যারে' শব্দার্থে সংশোধন করার পরিবর্তে, আমি মনে করি এটি আপনি যা চান:

function getSortedKeys(obj) {
    var keys = keys = Object.keys(obj);
    return keys.sort(function(a,b){return obj[b]-obj[a]});
}

জন্য সত্যিই পুরানো ব্রাউজারগুলি , পরিবর্তে এই ব্যবহার করুন:

function getSortedKeys(obj) {
    var keys = []; for(var key in obj) keys.push(key);
    return keys.sort(function(a,b){return obj[b]-obj[a]});
}

আপনি কোনও বস্তুতে ডাম্প (আপনার মত) এবং কীগুলির একটি অ্যারে পাবেন - এহ বৈশিষ্ট্য - পিছনে, এর, অ, অবজেক্টের মান, সংখ্যাসূচক মান অনুসারে সাজানো।

এটি কেবল তখনই কাজ করে যদি আপনার মানগুলি সংখ্যাসূচক হয়। function(a,b)আরোহী কাজ করার জন্য বাছাই করার পদ্ধতি পরিবর্তন করতে বা stringমানগুলির জন্য কাজ করার জন্য (উদাহরণস্বরূপ) সেখানে সামান্য টুইট করুন । পাঠকের জন্য অনুশীলন হিসাবে বাম।


4
এটি নিখুঁতভাবে কাজ করে এবং উপরের উত্তরটি কম কোডে
jshill103

4
আমার লক্ষ করা উচিত যে আজকাল বেশিরভাগ ব্রাউজারগুলি কেবলমাত্র অবজেক্ট.কিজ () - বিকাশকারী.মোজিলা.আর.ইন.ইউএস
ডকস / ওয়েব

অবজেক্ট.কিগুলি আরও ভাল কেন?
জন কেটজিক

4
@ জোহঙ্কটিজিক এই উত্তরটি 2012 :-) থেকে পেয়েছিলেন: অবজেক্ট.কিজ () আজকাল একটি মান, এবং এর সংক্ষিপ্ত এবং সম্ভবত আরও দ্রুত।
কমনপাইক

4
... :) আমি ক্লান্ত ছিলাম, আমাকে এটি মুছে ফেলুন
মানু

16

অব্যাহত আলোচনা এবং অন্যান্য সমাধানগুলি কীভাবে একটি (সাহসী) অ্যারেটিকে মান অনুসারে বাছাই করবেন তাতে আচ্ছাদিত ? সেরা সমাধান সহ (আমার ক্ষেত্রে) স্যামল দ্বারা হচ্ছে (নীচে উদ্ধৃত) )।

অ্যারেতে কেবল সংখ্যার সূচক থাকতে পারে। আপনাকে এটি কোনও অবজেক্ট, বা অবজেক্টের অ্যারে হিসাবে পুনর্লিখন করতে হবে।

var status = new Array();
status.push({name: 'BOB', val: 10});
status.push({name: 'TOM', val: 3});
status.push({name: 'ROB', val: 22});
status.push({name: 'JON', val: 7});

আপনি যদি status.pushপদ্ধতিটি পছন্দ করেন তবে আপনি এটি এর মাধ্যমে বাছাই করতে পারেন:

status.sort(function(a,b) {
    return a.val - b.val;
});

দুর্দান্ত! নামের ক্ষেত্রে আলফা বাছাই করতে: a.name> b.name ফিরুন।
এমপেমবার্ন

4
বর্ণানুক্রমিক বাছাইয়ের জন্য, একই ক্ষেত্রে স্ট্রিংয়ের মানগুলি তুলনা করুন কারণ sort()সেগুলি আলাদাভাবে আচরণ করে। আমি এই স্ট্যাকওভারফ্লো . com/Qestions/6712034/… উদাহরণ না পাওয়া পর্যন্ত এটি আমাকে এক ঘন্টা গণ্ডগোল করে Example a.name.toLowerCase() > b.name.toLowerCase()
ডিলান ভালাদ

5

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

আপনি আপনার অবজেক্টকে অবজেক্টের অ্যারে (কী / মান জোড়া) এ পরিণত করতে পারেন এবং এটি বাছাই করতে পারেন:

function sortObj(object, sortFunc) {
  var rv = [];
  for (var k in object) {
    if (object.hasOwnProperty(k)) rv.push({key: k, value:  object[k]});
  }
  rv.sort(function(o1, o2) {
    return sortFunc(o1.key, o2.key);
  });
  return rv;
}

তারপরে আপনি এটি তুলনামূলক ফাংশন সহ কল ​​করবেন call


+1 আপনি আমাকে এতে মারধর করেছেন। আমি একটি খুব অনুরূপ ব্যাখ্যা এবং কোড টুকরা লিখছিলাম।
গনচুকি

4

আপনি যদি টিপলস পছন্দ না করেন তবে এখানে বেন ফাঁকের উত্তরের একটি ভিন্নতা।

এটি আপনাকে কয়েকটি চরিত্র সংরক্ষণ করে।

var keys = [];
for (var key in sortme) {
  keys.push(key);
}

keys.sort(function(k0, k1) {
  var a = sortme[k0];
  var b = sortme[k1];
  return a < b ? -1 : (a > b ? 1 : 0);
});

for (var i = 0; i < keys.length; ++i) {
  var key = keys[i];
  var value = sortme[key];
  // Do something with key and value.
}

4

কোনও অপ্রয়োজনীয় জটিলতার প্রয়োজন নেই ...

function sortMapByValue(map)
{
    var tupleArray = [];
    for (var key in map) tupleArray.push([key, map[key]]);
    tupleArray.sort(function (a, b) { return a[1] - b[1] });
    return tupleArray;
}

এর আউটপুটটি অ্যারের অ্যারে, কোনও মানচিত্র নয়
ড্যানিয়েল

var stuff = {"a":1 , "b":3 , "c":0 } sortMapByValue(stuff) [Array[2], Array[2], Array[2]]
ড্যানিয়েল

আমি মনে করি এটি পরিষ্কার। শেষে একটি মানচিত্রে একটি রূপান্তর যুক্ত করুন
ড্যানিয়েল

1

আমি qu। জেচোরি ব্যবহার করি তবে আপনি এটি লুপের জন্য তৈরি করতে পারেন, একটি উন্নতি হ'ল:

        //.ArraySort(array)
        /* Sort an array
         */
        ArraySort = function(array, sortFunc){
              var tmp = [];
              var aSorted=[];
              var oSorted={};

              for (var k in array) {
                if (array.hasOwnProperty(k)) 
                    tmp.push({key: k, value:  array[k]});
              }

              tmp.sort(function(o1, o2) {
                    return sortFunc(o1.value, o2.value);
              });                     

              if(Object.prototype.toString.call(array) === '[object Array]'){
                  $.each(tmp, function(index, value){
                      aSorted.push(value.value);
                  });
                  return aSorted;                     
              }

              if(Object.prototype.toString.call(array) === '[object Object]'){
                  $.each(tmp, function(index, value){
                      oSorted[value.key]=value.value;
                  });                     
                  return oSorted;
              }               
     };

সুতরাং এখন আপনি করতে পারেন

    console.log("ArraySort");
    var arr1 = [4,3,6,1,2,8,5,9,9];
    var arr2 = {'a':4, 'b':3, 'c':6, 'd':1, 'e':2, 'f':8, 'g':5, 'h':9};
    var arr3 = {a: 'green', b: 'brown', c: 'blue', d: 'red'};
    var result1 = ArraySort(arr1, function(a,b){return a-b});
    var result2 = ArraySort(arr2, function(a,b){return a-b});
    var result3 = ArraySort(arr3, function(a,b){return a>b});
    console.log(result1);
    console.log(result2);       
    console.log(result3);

1

আমার মতামত অনুসারে এখানে নির্দিষ্ট মামলার জন্য সর্বোত্তম পন্থাটি হ'ল প্রস্তাবিত একটি কমনপাইক । সামান্য উন্নতি আমি সুপারিশ করব যে আধুনিক ব্রাউজারগুলিতে কাজ করে:

// aao is the "associative array" you need to "sort"
Object.keys(aao).sort(function(a,b){return aao[b]-aao[a]});

এটি সহজে প্রয়োগ হতে পারে এবং নির্দিষ্ট ক্ষেত্রে এখানে দুর্দান্ত কাজ করতে পারে যাতে আপনি এটি করতে পারেন:

let aoo={};
aao["sub2"]=1;
aao["sub0"]=-1;
aao["sub1"]=0;
aao["sub3"]=1;
aao["sub4"]=0;

let sk=Object.keys(aao).sort(function(a,b){return aao[b]-aao[a]});

// now you can loop using the sorted keys in `sk` to do stuffs
for (let i=sk.length-1;i>=0;--i){
 // do something with sk[i] or aoo[sk[i]]
}

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

// aao := is the "associative array" you need to "sort"
// comp := is the "field" you want to compare or "" if you have no "fields" and simply need to compare values
// intVal := must be false if you need comparing non-integer values
// desc := set to true will sort keys in descendant order (default sort order is ascendant)
function sortedKeys(aao,comp="",intVal=false,desc=false){
  let keys=Object.keys(aao);
  if (comp!="") {
    if (intVal) {
      if (desc) return keys.sort(function(a,b){return aao[b][comp]-aao[a][comp]});
      else return keys.sort(function(a,b){return aao[a][comp]-aao[a][comp]});
    } else {
      if (desc) return keys.sort(function(a,b){return aao[b][comp]<aao[a][comp]?1:aao[b][comp]>aao[a][comp]?-1:0});
      else return keys.sort(function(a,b){return aao[a][comp]<aao[b][comp]?1:aao[a][comp]>aao[b][comp]?-1:0});
    }
  } else {
    if (intVal) {
      if (desc) return keys.sort(function(a,b){return aao[b]-aao[a]});
      else return keys.sort(function(a,b){return aao[a]-aao[b]});
    } else {
      if (desc) return keys.sort(function(a,b){return aao[b]<aao[a]?1:aao[b]>aao[a]?-1:0});
      else return keys.sort(function(a,b){return aao[a]<aao[b]?1:aao[a]>aao[b]?-1:0});
    }
  }
}

আপনি নিম্নলিখিত কোডের মতো কিছু চেষ্টা করে কার্যকারিতা পরীক্ষা করতে পারেন:

let items={};
items['Edward']=21;
items['Sharpe']=37;
items['And']=45;
items['The']=-12;
items['Magnetic']=13;
items['Zeros']=37;
//equivalent to:
//let items={"Edward": 21, "Sharpe": 37, "And": 45, "The": -12, ...};

console.log("1: "+sortedKeys(items));
console.log("2: "+sortedKeys(items,"",false,true));
console.log("3: "+sortedKeys(items,"",true,false));
console.log("4: "+sortedKeys(items,"",true,true));
/* OUTPUT
1: And,Sharpe,Zeros,Edward,Magnetic,The
2: The,Magnetic,Edward,Sharpe,Zeros,And
3: The,Magnetic,Edward,Sharpe,Zeros,And
4: And,Sharpe,Zeros,Edward,Magnetic,The
*/

items={};
items['k1']={name:'Edward',value:21};
items['k2']={name:'Sharpe',value:37};
items['k3']={name:'And',value:45};
items['k4']={name:'The',value:-12};
items['k5']={name:'Magnetic',value:13};
items['k6']={name:'Zeros',value:37};

console.log("1: "+sortedKeys(items,"name"));
console.log("2: "+sortedKeys(items,"name",false,true));
/* OUTPUT
1: k6,k4,k2,k5,k1,k3
2: k3,k1,k5,k2,k4,k6
*/

আমি ইতিমধ্যে বলেছি, আপনি যদি স্টাফগুলি করতে চান তবে আপনি সাজানো কীগুলি লুপ করতে পারেন

let sk=sortedKeys(aoo);
// now you can loop using the sorted keys in `sk` to do stuffs
for (let i=sk.length-1;i>=0;--i){
 // do something with sk[i] or aoo[sk[i]]
}

অবশেষে , তবে অন্তত নয়, অবজেক্ট.কি এবং আরে.সোর্ট সম্পর্কিত কিছু দরকারী রেফারেন্স


0

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

let arr = [
    {a:1, b:2, c:3},
    {a:3, b:5, c:1},
    {a:2, b:3, c:9},
    {a:2, b:5, c:9},
    {a:2, b:3, c:10}    
]

function getSortedScore(obj) {
    var keys = []; 
    for(var key in obj[0]) keys.push(key);
    return obj.sort(function(a,b){
        for (var i in keys) {
            let k = keys[i];
            if (a[k]-b[k] > 0) return -1;
            else if (a[k]-b[k] < 0) return 1;
            else continue;
        };
    });
}

console.log(getSortedScore(arr))

আউটপুটস

 [ { a: 3, b: 5, c: 1 },
  { a: 2, b: 5, c: 9 },
  { a: 2, b: 3, c: 10 },
  { a: 2, b: 3, c: 9 },
  { a: 1, b: 2, c: 3 } ]

-4

@ সাধারণপাইকের উত্তরটি "সঠিক একটি" তবে তিনি মন্তব্য করতে গিয়ে ...

আজকাল বেশিরভাগ ব্রাউজার কেবল সমর্থন করে Object.keys()

হ্যাঁ .. Object.keys()হয় ভাল উপায়

তবে এর থেকে আরও ভাল কি ? দুহ, এটা ভিতরে coffeescript!

sortedKeys = (x) -> Object.keys(x).sort (a,b) -> x[a] - x[b]

sortedKeys
  'a' :  1
  'b' :  3
  'c' :  4
  'd' : -1

[ 'd', 'a', 'b', 'c' ]

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