दो क्षेत्रों द्वारा जावास्क्रिप्ट सॉर्ट सरणी


92
grouperArray.sort(function (a, b) {
    var aSize = a.gsize;
    var bSize = b.gsize;
    var aLow = a.glow;
    var bLow = b.glow;
    console.log(aLow + " | " + bLow);      
    return (aSize < bSize) ? -1 : (aSize > bSize) ? 1 : 0;
});

तो उपरोक्त कोड gsize द्वारा सरणी को सॉर्ट करता है - सबसे छोटा से सबसे बड़ा। यह अच्छा काम करता है। लेकिन अगर gsize वही है तो मैं चाहूंगा कि वह चमक के आधार पर छँटे।

धन्यवाद।


सॉर्ट फ़ंक्शन सकारात्मक, नकारात्मक या शून्य परिणाम पर प्रतिक्रिया करता है। तो आप बस लिख सकते हैं: "वापसी aSize - bSize"। यह अधिक सरल और पठनीय कोड होगा।

जवाबों:


112
grouperArray.sort(function (a, b) {
    var aSize = a.gsize;
    var bSize = b.gsize;
    var aLow = a.glow;
    var bLow = b.glow;
    console.log(aLow + " | " + bLow);

    if(aSize == bSize)
    {
        return (aLow < bLow) ? -1 : (aLow > bLow) ? 1 : 0;
    }
    else
    {
        return (aSize < bSize) ? -1 : 1;
    }
});

कुछ अन्य उत्तरों में दिखाई गई गैर-स्पष्ट तकनीकों का सहारा लिए बिना, तीर वाक्य रचना का उपयोग करके इसे और अधिक संक्षिप्त बनाने के लिए grouperArray.sort((a, b) => a.gsize == b.gsize ? a.glow - b.glow : a.gsize - b.gsize:। कोड को समझने में आसान बनाने के लिए, हम परीक्षण के लिए स्पष्ट रखते हैं ==
टूलमेकरसैट

171
grouperArray.sort(function (a, b) {   
    return a.gsize - b.gsize || a.glow - b.glow;
});

छोटा संस्करण


महान शॉर्ट कट! मुझे एक साथ और अधिक जटिल समाधान लगाने में मदद की .. stackoverflow.com/questions/6101475/…
जोसेफ पोइयर

3
अच्छा और साफ! केवल यह केवल संख्याओं के लिए काम करता है।
अफानासी कुराकिन

क्या आप यहाँ में तर्क समझा सकते हैं? यह मेरे लिए sort an array with a key's value firstऔर फिरsort the result with another key's value
KTM

1
@KTM तर्क निम्नानुसार है: यदि दोनों gsize समान हैं, तो स्थिति का पहला भाग 0 के बराबर है, जिसे गलत माना जाता है, और स्थिति का दूसरा भाग निष्पादित किया जाता है।
स्केलप्वेब

@Scalpweb हाँ :) तो यह किसी भी संख्या में कुंजियों की एक संख्या के साथ एक सरणी को क्रमबद्ध करने का काम करता है ?! अच्छी चाल
KTM

36
grouperArray.sort((a, b) => a.gsize - b.gsize || a.glow - b.glow);

तीर सिंटैक्स का उपयोग करके भी छोटा संस्करण!


3
सबसे संक्षिप्त और विस्तार योग्य, परिपूर्ण!
लॉरेंट

1
इससे भी कम, रिक्त स्थान बाहर निकालें:grouperArray.sort((a,b)=>a.gsize-b.gsize||a.glow-b.glow);
कप्तान शानदार

अगर आप यह समझना चाहते हैं कि आप उस काम को क्यों करना चाहते हैं, तो आप
http://www..com/ssareli/pss-ordering-is-a-monoid-61a4029387e

14

मुझे लगता है कि यह कुछ समय पहले पूछा गया था, लेकिन मुझे लगा कि मैं अपना समाधान जोड़ूंगा।

यह फ़ंक्शन डायनामिक तरीके से सॉर्ट मेथड बनाता है। बस आरोही या अवरोही क्रम को दर्शाने के लिए प्रत्येक सॉर्टेबल चाइल्ड प्रॉपर्टी के नाम को +/- के साथ सप्लाई करें। सुपर पुन: प्रयोज्य, और इसे आपके द्वारा एक साथ रखी गई डेटा संरचना के बारे में कुछ भी जानने की आवश्यकता नहीं है। बेवकूफ प्रमाण बनाया जा सकता है - लेकिन आवश्यक नहीं लगता है।

function getSortMethod(){
    var _args = Array.prototype.slice.call(arguments);
    return function(a, b){
        for(var x in _args){
            var ax = a[_args[x].substring(1)];
            var bx = b[_args[x].substring(1)];
            var cx;

            ax = typeof ax == "string" ? ax.toLowerCase() : ax / 1;
            bx = typeof bx == "string" ? bx.toLowerCase() : bx / 1;

            if(_args[x].substring(0,1) == "-"){cx = ax; ax = bx; bx = cx;}
            if(ax != bx){return ax < bx ? -1 : 1;}
        }
    }
}

उदाहरण का उपयोग:

items.sort (getSortMethod ('- मूल्य', '+ प्राथमिकता', '+ नाम'));

यह itemsसबसे priceपहले के साथ क्रमबद्ध होगा , सबसे अधिक के साथ आइटम के लिए जा रहे संबंधों के साथ priority। आइटम से आगे के संबंध टूट गए हैंname

जहाँ आइटम एक सरणी है जैसे:

var items = [
    { name: "z - test item", price: "99.99", priority: 0, reviews: 309, rating: 2 },
    { name: "z - test item", price: "1.99", priority: 0, reviews: 11, rating: 0.5 },
    { name: "y - test item", price: "99.99", priority: 1, reviews: 99, rating: 1 },
    { name: "y - test item", price: "0", priority: 1, reviews: 394, rating: 3.5 },
    { name: "x - test item", price: "0", priority: 2, reviews: 249, rating: 0.5 } ...
];

लाइव डेमो: http://gregtaff.com/misc/multi_field_sort/

संपादित करें: क्रोम के साथ फिक्स्ड मुद्दा।


यह शानदार है
Azure

प्रतिभाशाली उत्तर!
Marius

टाइपस्क्रिप्ट के लिए (a error TS2554: Expected 0 arguments, but got ..) नहीं मिल रहा है, यहाँ वाक्य रचना का उपयोग करें: stackoverflow.com/a/4116634/5287221
Chananel P

6

मुझे उम्मीद है कि टर्नरी ऑपरेटर ((aSize < bSize) ? -1 : (aSize > bSize) ? 1 : 0;)ने आपको भ्रमित किया है। आपको इसे बेहतर समझने के लिए लिंक को देखना चाहिए।

तब तक, यहाँ आपका कोड पूर्ण रूप से उड़ गया है यदि / और।

grouperArray.sort(function (a, b) {
    if (a.gsize < b.gsize)
    {
        return -1;
    }
    else if (a.gsize > b.gsize)
    {
        return 1;
    }
    else
    {
        if (a.glow < b.glow)
        {
            return -1;
        }
        else if (a.glow > b.glow)
        {
            return 1;
        }
        return 0;
    }
});

6

यहां उन लोगों के लिए एक कार्यान्वयन है जो कुछ अधिक सामान्य चाहते हैं जो किसी भी संख्या में फ़ील्ड के साथ काम करेंगे।

Array.prototype.sortBy = function (propertyName, sortDirection) {

    var sortArguments = arguments;
    this.sort(function (objA, objB) {

        var result = 0;
        for (var argIndex = 0; argIndex < sortArguments.length && result === 0; argIndex += 2) {

            var propertyName = sortArguments[argIndex];
            result = (objA[propertyName] < objB[propertyName]) ? -1 : (objA[propertyName] > objB[propertyName]) ? 1 : 0;

            //Reverse if sort order is false (DESC)
            result *= !sortArguments[argIndex + 1] ? 1 : -1;
        }
        return result;
    });

}

मूल रूप से, आप किसी भी संपत्ति का नाम / सॉर्ट दिशा निर्दिष्ट कर सकते हैं:

var arr = [{
  LastName: "Doe",
  FirstName: "John",
  Age: 28
}, {
  LastName: "Doe",
  FirstName: "Jane",
  Age: 28
}, {
  LastName: "Foo",
  FirstName: "John",
  Age: 30
}];

arr.sortBy("LastName", true, "FirstName", true, "Age", false);
//Will return Jane Doe / John Doe / John Foo

arr.sortBy("Age", false, "LastName", true, "FirstName", false);
//Will return John Foo / John Doe / Jane Doe

3
grouperArray.sort(function (a, b) {
  var aSize = a.gsize;
  var bSize = b.gsize;
  var aLow = a.glow;
  var bLow = b.glow;
  console.log(aLow + " | " + bLow);      
  return (aSize < bSize) ? -1 : (aSize > bSize) ? 1 : ( (aLow < bLow ) ? -1 : (aLow > bLow ) ? 1 : 0 );
});

3
grouperArray.sort(function (a, b) {
     var aSize = a.gsize;     
     var bSize = b.gsize;     
     var aLow = a.glow;
     var bLow = b.glow;
     console.log(aLow + " | " + bLow);
     return (aSize < bSize) ? -1 : (aSize > bSize) ? 1 : (aLow < bLow) ? -1 : (aLow > bLow) ? 1 : 0); }); 

3

यहां एक कार्यान्वयन है जो 1 से अनंत तक किसी भी प्रकार के सॉर्ट फ़ील्ड द्वारा पुनरावृत्ति का उपयोग करता है। आप इसे एक परिणाम सरणी पास करते हैं जो क्रमबद्ध करने के लिए परिणाम वस्तुओं की एक सरणी है, और एक प्रकार सरणी जो क्रमबद्ध वस्तुओं की एक सरणी है जो क्रम को परिभाषित करती है। प्रत्येक सॉर्ट ऑब्जेक्ट में कुंजी नाम के लिए "चयन करें" कुंजी होनी चाहिए जो उसके द्वारा क्रमबद्ध होती है और एक "ऑर्डर" कुंजी होती है जो "आरोही" या "अवरोही" इंगित करने वाली एक स्ट्रिंग है।

sortMultiCompare = (a, b, sorts) => {
    let select = sorts[0].select
    let order = sorts[0].order
    if (a[select] < b[select]) {
        return order == 'ascending' ? -1 : 1
    } 
    if (a[select] > b[select]) {
        return order == 'ascending' ? 1 : -1
    }
    if(sorts.length > 1) {
        let remainingSorts = sorts.slice(1)
        return this.sortMultiCompare(a, b, remainingSorts)
    }
    return 0
}

sortResults = (results, sorts) => {
    return results.sort((a, b) => {
        return this.sortMultiCompare(a, b, sorts)
    })
}

// example inputs
const results = [
    {
        "LastName": "Doe",
        "FirstName": "John",
        "MiddleName": "Bill"
    },
    {
        "LastName": "Doe",
        "FirstName": "Jane",
        "MiddleName": "Bill"
    },
    {
        "LastName": "Johnson",
        "FirstName": "Kevin",
        "MiddleName": "Bill"
    }
]

const sorts = [
    {
        "select": "LastName",
        "order": "ascending"
    },
    {
        "select": "FirstName",
        "order": "ascending"
    },
    {
        "select": "MiddleName",
        "order": "ascending"
    }    
]

// call the function like this:
let sortedResults = sortResults(results, sorts)

2

MULTIPLE कुंजियों के साथ ऐसा करने का एक गतिशील तरीका:

  • प्रत्येक कॉल / सॉर्ट की कुंजी से अद्वितीय मानों को फ़िल्टर करें
  • क्रम में रखना या उलट देना
  • indexOf (मान) कुंजी मानों के आधार पर प्रत्येक ऑब्जेक्ट के लिए वज़न चौड़ाई zeropad जोड़ें
  • caclutated वजन का उपयोग कर सॉर्ट करें

यहाँ छवि विवरण दर्ज करें

Object.defineProperty(Array.prototype, 'orderBy', {
value: function(sorts) { 
    sorts.map(sort => {            
        sort.uniques = Array.from(
            new Set(this.map(obj => obj[sort.key]))
        );

        sort.uniques = sort.uniques.sort((a, b) => {
            if (typeof a == 'string') {
                return sort.inverse ? b.localeCompare(a) : a.localeCompare(b);
            }
            else if (typeof a == 'number') {
                return sort.inverse ? (a < b) : (a > b ? 1 : 0);
            }
            else if (typeof a == 'boolean') {
                let x = sort.inverse ? (a === b) ? 0 : a? -1 : 1 : (a === b) ? 0 : a? 1 : -1;
                return x;
            }
            return 0;
        });
    });

    const weightOfObject = (obj) => {
        let weight = "";
        sorts.map(sort => {
            let zeropad = `${sort.uniques.length}`.length;
            weight += sort.uniques.indexOf(obj[sort.key]).toString().padStart(zeropad, '0');
        });
        //obj.weight = weight; // if you need to see weights
        return weight;
    }

    this.sort((a, b) => {
        return weightOfObject(a).localeCompare( weightOfObject(b) );
    });

    return this;
}
});

उपयोग:

// works with string, number and boolean
let sortered = your_array.orderBy([
    {key: "type", inverse: false}, 
    {key: "title", inverse: false},
    {key: "spot", inverse: false},
    {key: "internal", inverse: true}
]);

यहाँ छवि विवरण दर्ज करें


1

यही है वह जो मेरे द्वारा उपयोग किया जाता है

function sort(a, b) {
    var _a = "".concat(a.size, a.glow);
    var _b = "".concat(b.size, b.glow);
    return _a < _b;
}

एक स्ट्रिंग के रूप में दो वस्तुओं को मिलाएं और उन्हें एक स्ट्रिंग मान द्वारा सॉर्ट किया जाएगा। यदि आप चाहते हैं कि आप paraInt के साथ _a और _b को संख्याओं के रूप में तुलना करने के लिए लपेट सकते हैं यदि आपको पता है कि वे संख्यात्मक होंगे।


1

यहां केस का समाधान है, जब आपके पास प्राथमिकता सॉर्ट कुंजी है, जो कुछ विशेष वस्तुओं में मौजूद नहीं हो सकती है, इसलिए आपको फ़ॉलबैक कुंजी द्वारा सॉर्ट करना होगा।

एक इनपुट डेटा उदाहरण ( id2 प्राथमिकता प्राथमिकता कुंजी है):

const arr = [
    {id: 1},
    {id: 2, id2: 3},
    {id: 4},
    {id: 3},
    {id: 10, id2: 2},
    {id: 7},
    {id: 6, id2: 1},
    {id: 5},
    {id: 9, id2: 2},
    {id: 8},
];

और आउटपुट होना चाहिए:

[ { id: 6, id2: 1 },
  { id: 9, id2: 2 },
  { id: 10, id2: 2 },
  { id: 2, id2: 3 },
  { id: 1 },
  { id: 3 },
  { id: 4 },
  { id: 5 },
  { id: 7 },
  { id: 8 } ]

तुलनित्र कार्य इस प्रकार होगा:

arr.sort((a,b) => {
  if(a.id2 || b.id2) {
    if(a.id2 && b.id2) {
      if(a.id2 === b.id2) {
        return a.id - b.id;
      }
      return a.id2 - b.id2;
    }
    return a.id2 ? -1 : 1;
  }
  return a.id - b.id
});

पुनश्च में मामला अगर .id की .id2 शून्य हो सकता है, का उपयोग करने के लिए विचार typeof


0
grouperArray.sort(
  function(a,b){return a.gsize == b.gsize ? a.glow - b.glow : a.gsize - b.gsize}
);

0
grouperArray.sort(function (a, b) {
    var aSize = a.gsize;
    var bSize = b.gsize;
    if (aSize !== aSize)
        return aSize - bSize;
    return a.glow - b.glow;
});

परीक्षण नहीं किया गया है, लेकिन मुझे लगता है कि काम करना चाहिए।


0

मेरे मामले में, मैं 'महत्वपूर्ण' और 'तारीख' द्वारा अधिसूचना सूची को सॉर्ट करता हूं

  • चरण 1: मैं 'महत्वपूर्ण' और महत्वहीन द्वारा सूचनाओं को फ़िल्टर करता हूँ

    let importantNotifications = notifications.filter(
            (notification) => notification.isImportant);
    
      let unImportantNotifications = notifications.filter(
            (notification) => !notification.isImportant);
    
  • चरण 2: मैं उन्हें तिथि के अनुसार क्रमबद्ध करता हूं

      sortByDate = (notifications) => {
      return notifications.sort((notificationOne, notificationTwo) => {
        return notificationOne.date - notificationTwo.date;
      });
    };
    
  • चरण 3: उन्हें मर्ज करें

    [
        ...this.sortByDate(importantNotifications),
        ...this.sortByDate(unImportantNotifications),
      ];
    
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.