Сортировка объектов по значениям свойств


88

Как реализовать следующий сценарий, используя только Javascript:

  • Создайте объект автомобиля со свойствами (максимальная скорость, марка и т. Д.)
  • Отсортировать список автомобилей по этим свойствам

3
@durilai: JavaScript является объектно - ориентированным, ОО модель JavaScript основан на прототипирования и действительно, на самом деле универсальны ... en.wikipedia.org/wiki/Prototype-based_programming
Christian C. Salvado

Я рекомендую использовать lodash.js: lodash.com/docs#sortBy
Chemical Programmer

Ответы:


159

javascript имеет функцию сортировки, которая может принимать другую функцию в качестве параметра - эта вторая функция используется для сравнения двух элементов.

Пример:

cars = [

    {
        name: "Honda",
        speed: 80
    },

    {
        name: "BMW",
        speed: 180
    },

    {
        name: "Trabi",
        speed: 40
    },

    {
        name: "Ferrari",
        speed: 200
    }
]


cars.sort(function(a, b) { 
    return a.speed - b.speed;
})

for(var i in cars)
    document.writeln(cars[i].name) // Trabi Honda BMW Ferrari 

хорошо, из вашего комментария я вижу, что вы используете слово «сортировка» в неправильном смысле. В программировании «сортировка» означает «расставить вещи в определенном порядке», а не «расставить вещи по группам». Последний вариант намного проще - именно так вы «сортируете» вещи в реальном мире.

  • сделать два пустых массива («ящики»)
  • для каждого объекта в вашем списке проверьте, соответствует ли он критериям
  • если да, поместите его в первую «коробку»
  • если нет, поместите его во вторую «коробку»

10
Простое примечание для удобства: this ( a.someProp - b.someProp) сортирует от наименьшего к высшему , а reverse ( b.someProp - a.someProp) сортирует от высшего к низшему. В основном, если функция возвращает меньше 0, a стоит перед b.
user56reinstatemonica8 06

Также обратите внимание, что это решение работает только тогда, когда свойства, по которым вы сортируете, являются числами. Это работает в примере для сортировки по максимальной скорости, но если вы хотите сортировать по марке автомобиля, это решение не будет сортировать строки по алфавиту. Cheeso предоставляет ответ для сортировки как по числам, так и по строкам.
Коул Маршалл

23

Пример.

Это работает на cscript.exe в Windows.

// define the Car class
(function() {
    // makeClass - By John Resig (MIT Licensed)
    // Allows either new User() or User() to be employed for construction.
    function makeClass(){
        return function(args){
            if ( this instanceof arguments.callee ) {
                if ( typeof this.init == "function" )
                    this.init.apply( this, (args && args.callee) ? args : arguments );
            } else
                return new arguments.callee( arguments );
        };
    }

    Car = makeClass();

    Car.prototype.init = function(make, model, price, topSpeed, weight) {
        this.make = make;
        this.model = model;
        this.price = price;
        this.weight = weight;
        this.topSpeed = topSpeed;
    };
})();


// create a list of cars
var autos = [
    new Car("Chevy", "Corvair", 1800, 88, 2900),
    new Car("Buick", "LeSabre", 31000, 138, 3700),
    new Car("Toyota", "Prius", 24000, 103, 3200),
    new Car("Porsche", "911", 92000, 155, 3100),
    new Car("Mercedes", "E500", 67000, 145, 3800),
    new Car("VW", "Passat", 31000, 135, 3700)
];

// a list of sorting functions
var sorters = {
    byWeight : function(a,b) {
        return (a.weight - b.weight);
    },
    bySpeed : function(a,b) {
        return (a.topSpeed - b.topSpeed);
    },
    byPrice : function(a,b) {
        return (a.price - b.price);
    },
    byModelName : function(a,b) {
        return ((a.model < b.model) ? -1 : ((a.model > b.model) ? 1 : 0));
    },
    byMake : function(a,b) {
        return ((a.make < b.make) ? -1 : ((a.make > b.make) ? 1 : 0));
    }
};

function say(s) {WScript.Echo(s);}

function show(title)
{
    say ("sorted by: "+title);
    for (var i=0; i < autos.length; i++) {
        say("  " + autos[i].model);
    }
    say(" ");
}

autos.sort(sorters.byWeight);
show("Weight");

autos.sort(sorters.byModelName);
show("Name");

autos.sort(sorters.byPrice);
show("Price");

Также можно сделать общий сортировщик.

var byProperty = function(prop) {
    return function(a,b) {
        if (typeof a[prop] == "number") {
            return (a[prop] - b[prop]);
        } else {
            return ((a[prop] < b[prop]) ? -1 : ((a[prop] > b[prop]) ? 1 : 0));
        }
    };
};

autos.sort(byProperty("topSpeed"));
show("Top Speed");

13

Я написал для себя эту простую функцию:

function sortObj(list, key) {
    function compare(a, b) {
        a = a[key];
        b = b[key];
        var type = (typeof(a) === 'string' ||
                    typeof(b) === 'string') ? 'string' : 'number';
        var result;
        if (type === 'string') result = a.localeCompare(b);
        else result = a - b;
        return result;
    }
    return list.sort(compare);
}

например у вас есть список автомобилей:

var cars= [{brand: 'audi', speed: 240}, {brand: 'fiat', speed: 190}];
var carsSortedByBrand = sortObj(cars, 'brand');
var carsSortedBySpeed = sortObj(cars, 'speed');

6

Допустим, нам нужно отсортировать список объектов в порядке возрастания на основе определенного свойства, в этом примере допустим, что мы должны отсортировать на основе свойства «имя», а затем ниже приведен требуемый код:

var list_Objects = [{"name"="Bob"},{"name"="Jay"},{"name"="Abhi"}];
Console.log(list_Objects);   //[{"name"="Bob"},{"name"="Jay"},{"name"="Abhi"}]
    list_Objects.sort(function(a,b){
        return a["name"].localeCompare(b["name"]); 
    });
Console.log(list_Objects);  //[{"name"="Abhi"},{"name"="Bob"},{"name"="Jay"}]

1
Думаю, у вас опечатка? вернуть ["имя"]. localeCompare (b. ["имя"]); должен быть возвращен a ["имя"]. localeCompare (b ["имя"]); (удалите. после b)
Little Brain

3

Со стрелочными функциями ES6 это будет так:

//Let's say we have these cars
let cars = [ { brand: 'Porsche', top_speed: 260 },
  { brand: 'Benz', top_speed: 110 },
  { brand: 'Fiat', top_speed: 90 },
  { brand: 'Aston Martin', top_speed: 70 } ]

Array.prototype.sort() может принимать функцию компаратора (здесь я использовал обозначения стрелок, но обычные функции работают так же):

let sortedByBrand = [...cars].sort((first, second) => first.brand > second.brand)

// [ { brand: 'Aston Martin', top_speed: 70 },
//   { brand: 'Benz', top_speed: 110 },
//   { brand: 'Fiat', top_speed: 90 },
//   { brand: 'Porsche', top_speed: 260 } ]

Приведенный выше подход копирует содержимое массива cars в новый и сортирует его в алфавитном порядке по названиям брендов. Точно так же вы можете передать другую функцию:

let sortedBySpeed =[...cars].sort((first, second) => first.top_speed > second.top_speed)

//[ { brand: 'Aston Martin', top_speed: 70 },
//  { brand: 'Fiat', top_speed: 90 },
//  { brand: 'Benz', top_speed: 110 },
//  { brand: 'Porsche', top_speed: 260 } ]

Если вы не возражаете против изменения исходного массива, это cars.sort(comparatorFunction)поможет.


3

Вот небольшой пример, который создает массив объектов и сортирует их в числовом или алфавитном порядке:

// Create Objects Array

var arrayCarObjects = [
{brand: "Honda",        topSpeed: 45},
{brand: "Ford",         topSpeed: 6},
{brand: "Toyota",       topSpeed: 240},
{brand: "Chevrolet",    topSpeed: 120},
{brand: "Ferrari",      topSpeed: 1000}
];

// Sort Objects Numerically

arrayCarObjects.sort((a, b) => (a.topSpeed - b.topSpeed));

// Sort Objects Alphabetically

arrayCarObjects.sort((a, b) => (a.brand > b.brand) ? 1 : -1);

2

Версия решения Cheeso с обратной сортировкой, я также удалил троичные выражения из-за отсутствия ясности (но это личный вкус).

function(prop, reverse) {
  return function(a, b) {
    if (typeof a[prop] === 'number') {
      return (a[prop] - b[prop]);
    }

    if (a[prop] < b[prop]) {
      return reverse ? 1 : -1;
    }

    if (a[prop] > b[prop]) {
      return reverse ? -1 : 1;
    }

    return 0;
  };
};

1
Чтобы полностью return !!reverse ? (a[prop] - b[prop]) * -1 : (a[prop] - b[prop]);
Марк

Да, поскольку теперь нет обратной проверки номеров, спасибо, я должен это исправить. Но почему дубль !это тоже нормально:return reverse ? (a[prop] - b[prop]) * -1 : (a[prop] - b[prop]);
Marcs

1
!!Тип силы принуждения к нативной значения логического типа , в отличие от «falsy» характер ценности JavaScript, строго говоря , не требуется , но проясняет назначения , по крайней мере для меня. Обратите внимание, что когда вы возвращаете значение с !!этим логическим типом, это собственный логический тип, в отличие от собственного типа с «ложным» значением, которое означает, что typeof !!undefinedили typeof !!nullи т. Д. Возвращают «логическое». Обратите внимание, что !!" "это trueно !!""есть false(пробел, нет пробела в строка), но вы, вероятно, уже это знали.
Mark Schultheiss
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.