sort - فرز مصفوفة من كائنات JavaScript




sort() python (16)

أوصي GitHub: Array sortBy - أفضل تطبيق من أسلوب sortBy الذي يستخدم التحويل Schwartzian

ولكن في الوقت الحالي ، سنجرب هذا الأسلوب Gist: sortBy-old.js .
دعونا إنشاء طريقة لفرز صفائف قادرة على ترتيب الأشياء من قبل بعض الممتلكات.

خلق وظيفة الفرز

var sortBy = (function () {
  var toString = Object.prototype.toString,
      // default parser function
      parse = function (x) { return x; },
      // gets the item to be sorted
      getItem = function (x) {
        var isObject = x != null && typeof x === "object";
        var isProp = isObject && this.prop in x;
        return this.parser(isProp ? x[this.prop] : x);
      };

  /**
   * Sorts an array of elements.
   *
   * @param  {Array} array: the collection to sort
   * @param  {Object} cfg: the configuration options
   * @property {String}   cfg.prop: property name (if it is an Array of objects)
   * @property {Boolean}  cfg.desc: determines whether the sort is descending
   * @property {Function} cfg.parser: function to parse the items to expected type
   * @return {Array}
   */
  return function sortby (array, cfg) {
    if (!(array instanceof Array && array.length)) return [];
    if (toString.call(cfg) !== "[object Object]") cfg = {};
    if (typeof cfg.parser !== "function") cfg.parser = parse;
    cfg.desc = !!cfg.desc ? -1 : 1;
    return array.sort(function (a, b) {
      a = getItem.call(cfg, a);
      b = getItem.call(cfg, b);
      return cfg.desc * (a < b ? -1 : +(a > b));
    });
  };

}());

ضبط البيانات التي لم يتم فرزها

var data = [
  {date: "2011-11-14T16:30:43Z", quantity: 2, total: 90,  tip: 0,   type: "tab"},
  {date: "2011-11-14T17:22:59Z", quantity: 2, total: 90,  tip: 0,   type: "Tab"},
  {date: "2011-11-14T16:28:54Z", quantity: 1, total: 300, tip: 200, type: "visa"},
  {date: "2011-11-14T16:53:41Z", quantity: 2, total: 90,  tip: 0,   type: "tab"},
  {date: "2011-11-14T16:48:46Z", quantity: 2, total: 90,  tip: 0,   type: "tab"},
  {date: "2011-11-14T17:25:45Z", quantity: 2, total: 200, tip: 0,   type: "cash"},
  {date: "2011-11-31T17:29:52Z", quantity: 1, total: 200, tip: 100, type: "Visa"},
  {date: "2011-11-14T16:58:03Z", quantity: 2, total: 90,  tip: 0,   type: "tab"},
  {date: "2011-11-14T16:20:19Z", quantity: 2, total: 190, tip: 100, type: "tab"},
  {date: "2011-11-01T16:17:54Z", quantity: 2, total: 190, tip: 100, type: "tab"},
  {date: "2011-11-14T17:07:21Z", quantity: 2, total: 90,  tip: 0,   type: "tab"},
  {date: "2011-11-14T16:54:06Z", quantity: 1, total: 100, tip: 0,   type: "Cash"}
];

استخدامه

ترتيب الصفيف ، من خلال "date" String

// sort by @date (ascending)
sortBy(data, { prop: "date" });

// expected: first element
// { date: "2011-11-01T16:17:54Z", quantity: 2, total: 190, tip: 100, type: "tab" }

// expected: last element
// { date: "2011-11-31T17:29:52Z", quantity: 1, total: 200, tip: 100, type: "Visa"}

إذا كنت تريد تجاهل حالة الأحرف ، قم بتعيين استدعاء parser :

// sort by @type (ascending) IGNORING case-sensitive
sortBy(data, {
    prop: "type",
    parser: (t) => t.toUpperCase()
});

// expected: first element
// { date: "2011-11-14T16:54:06Z", quantity: 1, total: 100, tip: 0, type: "Cash" }

// expected: last element
// { date: "2011-11-31T17:29:52Z", quantity: 1, total: 200, tip: 100, type: "Visa" }

إذا كنت تريد تحويل حقل "date" كنوع Date :

// sort by @date (descending) AS Date object
sortBy(data, {
    prop: "date",
    desc: true,
    parser: (d) => new Date(d)
});

// expected: first element
// { date: "2011-11-31T17:29:52Z", quantity: 1, total: 200, tip: 100, type: "Visa"}

// expected: last element
// { date: "2011-11-01T16:17:54Z", quantity: 2, total: 190, tip: 100, type: "tab" }

هنا يمكنك اللعب بالرمز: jsbin.com/lesebi

بفضل @ أوزيش من خلال ملاحظاته ، تم إصلاح المشكلة المتعلقة بالخواص ذات القيم الزائفة .

https://code.i-harness.com

قرأت الأشياء التالية باستخدام Ajax وقمت بتخزينها في مصفوفة:

var homes = [
    {
        "h_id": "3",
        "city": "Dallas",
        "state": "TX",
        "zip": "75201",
        "price": "162500"
    }, {
        "h_id": "4",
        "city": "Bevery Hills",
        "state": "CA",
        "zip": "90210",
        "price": "319250"
    }, {
        "h_id": "5",
        "city": "New York",
        "state": "NY",
        "zip": "00010",
        "price": "962500"
    }
];

كيف أقوم بإنشاء دالة لفرز الكائنات حسب خاصية price بترتيب تصاعدي أو تنازلي باستخدام JavaScript فقط؟


إذا كان لديك متصفح متوافق مع ES6 فيمكنك استخدام:

الفرق بين ترتيب الفرز التصاعدي والتنازلي هو علامة القيمة التي تم إرجاعها بواسطة دالة المقارنة:

var ascending = homes.sort((a, b) => Number(a.price) - Number(b.price));
var descending = homes.sort((a, b) => Number(b.price) - Number(a.price));

إليك مقتطف شفرة العمل:

var homes = [{
  "h_id": "3",
  "city": "Dallas",
  "state": "TX",
  "zip": "75201",
  "price": "162500"
}, {
  "h_id": "4",
  "city": "Bevery Hills",
  "state": "CA",
  "zip": "90210",
  "price": "319250"
}, {
  "h_id": "5",
  "city": "New York",
  "state": "NY",
  "zip": "00010",
  "price": "962500"
}];

var ascending = homes.sort((a, b) => Number(a.price) - Number(b.price));
var descending = homes.sort((a, b) => Number(b.price) - Number(a.price));

console.log("ascending", ascending);
console.log("descending", descending);


إليك إصدار أكثر مرونة ، والذي يسمح لك بإنشاء وظائف فرز قابلة لإعادة الاستخدام ، والفرز حسب أي حقل.

var sort_by = function(field, reverse, primer){

   var key = primer ? 
       function(x) {return primer(x[field])} : 
       function(x) {return x[field]};

   reverse = !reverse ? 1 : -1;

   return function (a, b) {
       return a = key(a), b = key(b), reverse * ((a > b) - (b > a));
     } 
}

الآن يمكنك الفرز حسب أي مجال في الإرادة ...

var homes = [{

   "h_id": "3",
   "city": "Dallas",
   "state": "TX",
   "zip": "75201",
   "price": "162500"

}, {

   "h_id": "4",
   "city": "Bevery Hills",
   "state": "CA",
   "zip": "90210",
   "price": "319250"

}, {

   "h_id": "5",
   "city": "New York",
   "state": "NY",
   "zip": "00010",
   "price": "962500"

}];

// Sort by price high to low
homes.sort(sort_by('price', true, parseInt));

// Sort by city, case-insensitive, A-Z
homes.sort(sort_by('city', false, function(a){return a.toUpperCase()}));

استخدام lodash.sortBy ، (تعليمات باستخدام commonjs ، يمكنك أيضًا وضع علامة التضمين النصي للـ cdn أعلى HTML)

var sortBy = require('lodash.sortby');
// or
sortBy = require('lodash').sortBy;

تنازليا

var descendingOrder = sortBy( homes, 'price' ).reverse();

ترتيب تصاعدي

var ascendingOrder = sortBy( homes, 'price' );

ترتيب المنازل حسب السعر بترتيب تصاعدي:

homes.sort(function(a, b) {
    return parseFloat(a.price) - parseFloat(b.price);
});

أو بعد إصدار ES6:

homes.sort((a, b) => parseFloat(a.price) - parseFloat(b.price));

يمكن العثور على بعض الوثائق here .


تريد فرزها في Javascript ، أليس كذلك؟ ما تريده هو وظيفة sort() . في هذه الحالة تحتاج إلى كتابة وظيفة مقارنة وتمريرها sort() ، لذلك شيء من هذا القبيل:

function comparator(a, b) {
    return parseInt(a["price"], 10) - parseInt(b["price"], 10);
}

var json = { "homes": [ /* your previous data */ ] };
console.log(json["homes"].sort(comparator));

تأخذ المقارنة الخاصة بك واحدة من كل من تجزئات متداخلة داخل الصفيف وتقرر أي واحد أعلى عن طريق التحقق من حقل "السعر".


على الرغم من أن ذلك يمثل نوعًا من المبالغة في الاكتفاء بفرز مصفوفة واحدة فقط ، إلا أن وظيفة النموذج الأولي هذه تسمح بفرز مصفوفات جافا سكريبت من خلال أي مفتاح ، بترتيب تصاعدي أو تنازلي ، بما في ذلك المفاتيح المتداخلة ، باستخدام بناء الجملة dot .

(function(){
    var keyPaths = [];

    var saveKeyPath = function(path) {
        keyPaths.push({
            sign: (path[0] === '+' || path[0] === '-')? parseInt(path.shift()+1) : 1,
            path: path
        });
    };

    var valueOf = function(object, path) {
        var ptr = object;
        for (var i=0,l=path.length; i<l; i++) ptr = ptr[path[i]];
        return ptr;
    };

    var comparer = function(a, b) {
        for (var i = 0, l = keyPaths.length; i < l; i++) {
            aVal = valueOf(a, keyPaths[i].path);
            bVal = valueOf(b, keyPaths[i].path);
            if (aVal > bVal) return keyPaths[i].sign;
            if (aVal < bVal) return -keyPaths[i].sign;
        }
        return 0;
    };

    Array.prototype.sortBy = function() {
        keyPaths = [];
        for (var i=0,l=arguments.length; i<l; i++) {
            switch (typeof(arguments[i])) {
                case "object": saveKeyPath(arguments[i]); break;
                case "string": saveKeyPath(arguments[i].match(/[+-]|[^.]+/g)); break;
            }
        }
        return this.sort(comparer);
    };    
})();

الاستعمال:

var data = [
    { name: { first: 'Josh', last: 'Jones' }, age: 30 },
    { name: { first: 'Carlos', last: 'Jacques' }, age: 19 },
    { name: { first: 'Carlos', last: 'Dante' }, age: 23 },
    { name: { first: 'Tim', last: 'Marley' }, age: 9 },
    { name: { first: 'Courtney', last: 'Smith' }, age: 27 },
    { name: { first: 'Bob', last: 'Smith' }, age: 30 }
]

data.sortBy('age'); // "Tim Marley(9)", "Carlos Jacques(19)", "Carlos Dante(23)", "Courtney Smith(27)", "Josh Jones(30)", "Bob Smith(30)"

الفرز حسب الخصائص المتداخلة مع بناء الجملة أو بناء جملة الصفيف:

data.sortBy('name.first'); // "Bob Smith(30)", "Carlos Dante(23)", "Carlos Jacques(19)", "Courtney Smith(27)", "Josh Jones(30)", "Tim Marley(9)"
data.sortBy(['name', 'first']); // "Bob Smith(30)", "Carlos Dante(23)", "Carlos Jacques(19)", "Courtney Smith(27)", "Josh Jones(30)", "Tim Marley(9)"

الفرز بواسطة مفاتيح متعددة:

data.sortBy('name.first', 'age'); // "Bob Smith(30)", "Carlos Jacques(19)", "Carlos Dante(23)", "Courtney Smith(27)", "Josh Jones(30)", "Tim Marley(9)"
data.sortBy('name.first', '-age'); // "Bob Smith(30)", "Carlos Dante(23)", "Carlos Jacques(19)", "Courtney Smith(27)", "Josh Jones(30)", "Tim Marley(9)"

يمكنك شوكة الريبو: https://github.com/eneko/Array.sortBy


عملت أيضا مع نوع من التقييم ومجالات متعددة الفرز:

arr = [
    {type:'C', note:834},
    {type:'D', note:732},
    {type:'D', note:008},
    {type:'F', note:474},
    {type:'P', note:283},
    {type:'P', note:165},
    {type:'X', note:173},
    {type:'Z', note:239},
];

arr.sort(function(a,b){        
    var _a = ((a.type==='C')?'0':(a.type==='P')?'1':'2');
    _a += (a.type.localeCompare(b.type)===-1)?'0':'1';
    _a += (a.note>b.note)?'1':'0';
    var _b = ((b.type==='C')?'0':(b.type==='P')?'1':'2');
    _b += (b.type.localeCompare(a.type)===-1)?'0':'1';
    _b += (b.note>a.note)?'1':'0';
    return parseInt(_a) - parseInt(_b);
});

نتيجة

[
    {"type":"C","note":834},
    {"type":"P","note":165},
    {"type":"P","note":283},
    {"type":"D","note":8},
    {"type":"D","note":732},
    {"type":"F","note":474},
    {"type":"X","note":173},
    {"type":"Z","note":239}
]

كتبت مؤخرا وظيفة عالمية لإدارة هذا لك إذا كنت ترغب في استخدامه.

/**
 * Sorts an object into an order
 *
 * @require jQuery
 *
 * @param object Our JSON object to sort
 * @param type Only alphabetical at the moment
 * @param identifier The array or object key to sort by
 * @param order Ascending or Descending
 *
 * @returns Array
 */
function sortItems(object, type, identifier, order){

    var returnedArray = [];
    var emptiesArray = []; // An array for all of our empty cans

    // Convert the given object to an array
    $.each(object, function(key, object){

        // Store all of our empty cans in their own array
        // Store all other objects in our returned array
        object[identifier] == null ? emptiesArray.push(object) : returnedArray.push(object);

    });

    // Sort the array based on the type given
    switch(type){

        case 'alphabetical':

            returnedArray.sort(function(a, b){

                return(a[identifier] == b[identifier]) ? 0 : (

                    // Sort ascending or descending based on order given
                    order == 'asc' ? a[identifier] > b[identifier] : a[identifier] < b[identifier]

                ) ? 1 : -1;

            });

            break;

        default:

    }

    // Return our sorted array along with the empties at the bottom depending on sort order
    return order == 'asc' ? returnedArray.concat(emptiesArray) : emptiesArray.concat(returnedArray);

}

لفرز ذلك ، تحتاج إلى إنشاء وظيفة مقارنة تأخذ حجتين. ثم استدعاء دالة الفرز مع وظيفة المقارنة هذه على النحو التالي:

// a and b are object elements of your array
function mycomparator(a,b) {
  return parseInt(a.price, 10) - parseInt(b.price, 10);
}
homes.sort(mycomparator);

إذا كنت ترغب في فرز تصاعدي تبديل التعبيرات على كل جانب من علامة الطرح.


لفرز على حقل كائن مجموعة متعددة. أدخل اسم الحقل الخاص بك في مصفوفة arrprop مثل ["a","b","c"] ثم مرر في المصدر الفعلي المصدر الفعلي للمصدر الذي نريد فرزه.

function SortArrayobject(arrprop,arrsource){
arrprop.forEach(function(i){
arrsource.sort(function(a,b){
return ((a[i] < b[i]) ? -1 : ((a[i] > b[i]) ? 1 : 0));
});
});
return arrsource;
}

لفرز مصفوفة يجب عليك تحديد وظيفة مقارنة. تكون هذه الوظيفة مختلفة دائمًا عن نمط الفرز أو الترتيب المطلوب (أي تصاعدي أو تنازلي).

السماح بإنشاء بعض الوظائف التي تقوم بتصنيف صفيف تصاعدي أو تنازلي ويحتوي على كائن أو سلسلة أو قيم رقمية.

function sorterAscending(a,b) {
    return a-b;
}

function sorterDescending(a,b) {
    return b-a;
}

function sorterPriceAsc(a,b) {
    return parseInt(a['price']) - parseInt(b['price']);
}

function sorterPriceDes(a,b) {
    return parseInt(b['price']) - parseInt(b['price']);
}

فرز الأرقام (حسب الترتيب الأبجدي والصاعد):

var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.sort();

فرز الأرقام (أبجديا وتنازليا):

var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.sort();
fruits.reverse();

فرز الأرقام (عدديًا وصاعدًا):

var points = [40,100,1,5,25,10];
points.sort(sorterAscending());

فرز الأرقام (عدديًا وتنازليًا):

var points = [40,100,1,5,25,10];
points.sort(sorterDescending());

كما ورد أعلاه ، استخدم sorterPriceAsc و sorterPriceDes طريقة مع الصفيف الخاص بك مع المفتاح المطلوب.

homes.sort(sorterPriceAsc()) or homes.sort(sorterPriceDes())

مع إجابة ECMAScript 6 ستوبور يمكن أن يكون أكثر إيجازا:

homes.sort((a, b) => a.price - b.price)


هنا نسخة معدلة قليلاً من التنفيذ الأنيق من كتاب "JavaScript: The Good Parts".

ملاحظة : هذا الإصدار من by مستقر . يحتفظ ترتيب الفرز الأول أثناء تنفيذ الفرز التالي بالسلاسل.

لقد أضفت معلمة isAscending إليها. أيضا تحويله إلى معايير ES6 وأجزاء جيدة "أحدث" على النحو الموصى به من قبل المؤلف.

يمكنك فرز تصاعدي وكذلك فرز تنازلي وسلسلة حسب خصائص متعددة.

const by = function (name, minor, isAscending=true) {
    const reverseMutliplier = isAscending ? 1 : -1;
    return function (o, p) {
        let a, b;
        let result;
        if (o && p && typeof o === "object" && typeof p === "object") {
            a = o[name];
            b = p[name];
            if (a === b) {
                return typeof minor === 'function' ? minor(o, p) : 0;
            }
            if (typeof a === typeof b) {
                result = a < b ? -1 : 1;
            } else {
                result = typeof a < typeof b ? -1 : 1;
            }
            return result * reverseMutliplier;
        } else {
            throw {
                name: "Error",
                message: "Expected an object when sorting by " + name
            };
        }
    };
};

let s = [
    {first: 'Joe',   last: 'Besser'},
    {first: 'Moe',   last: 'Howard'},
    {first: 'Joe',   last: 'DeRita'},
    {first: 'Shemp', last: 'Howard'},
    {first: 'Larry', last: 'Fine'},
    {first: 'Curly', last: 'Howard'}
];

// Sort by: first ascending, last ascending
s.sort(by("first", by("last")));    
console.log("Sort by: first ascending, last ascending: ", s);     // "[
//     {"first":"Curly","last":"Howard"},
//     {"first":"Joe","last":"Besser"},     <======
//     {"first":"Joe","last":"DeRita"},     <======
//     {"first":"Larry","last":"Fine"},
//     {"first":"Moe","last":"Howard"},
//     {"first":"Shemp","last":"Howard"}
// ]

// Sort by: first ascending, last descending
s.sort(by("first", by("last", 0, false)));  
console.log("sort by: first ascending, last descending: ", s);    // "[
//     {"first":"Curly","last":"Howard"},
//     {"first":"Joe","last":"DeRita"},     <========
//     {"first":"Joe","last":"Besser"},     <========
//     {"first":"Larry","last":"Fine"},
//     {"first":"Moe","last":"Howard"},
//     {"first":"Shemp","last":"Howard"}
// ]


يمكنك استخدام طريقة sort JavaScript مع وظيفة رد الاتصال:

function compareASC(homeA, homeB)
{
    return parseFloat(homeA.price) - parseFloat(homeB.price);
}

function compareDESC(homeA, homeB)
{
    return parseFloat(homeB.price) - parseFloat(homeA.price);
}

// Sort ASC
homes.sort(compareASC);

// Sort DESC
homes.sort(compareDESC);




sorting