按属性值对对象排序


88

如何仅使用Javascript实现以下方案:

  • 创建具有属性(最高速度,品牌等)的汽车对象
  • 对这些属性订购的汽车列表进行排序

3
@durilai:JavaScript面向对象的,JavaScript的OO模型基于原型,并且确实非常通用…… en.wikipedia.org
wiki/Prototype

我建议使用lodash.js:lodash.com/docs#sortBy
Chemical Programmer

Answers:


159

javascript具有sort函数,该函数可以将另一个函数用作参数-第二个函数用于比较两个元素。

例:

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 

好的,从您的评论中我发现您使用的“ sort”一词含义不正确。在编程中,“排序”是指“按一定顺序放置事物”,而不是“按组排列事物”。后者要简单得多-这就是您在现实世界中对事物进行“分类”的方式

  • 制作两个空数组(“框”)
  • 对于列表中的每个对象,检查其是否符合条件
  • 如果是,将其放在第一个“框”中
  • 如果否,将其放在第二个“框”中

10
为方便起见,以下为简单注释:this(a.someProp - b.someProp)从最低到最高排序,反向(b.someProp - a.someProp)从最高到最低排序。基本上,如果函数返回的值小于0,则a在b之前。
user56reinstatemonica8'8

还要注意,此解决方案仅适用于您要排序的属性是数字时。该示例在按最高速度排序的示例中有效,但如果要按汽车品牌排序,则此解决方案不会按字母顺序对字符串进行排序。Cheeso提供了按数字和字符串排序的答案。
科尔·马歇尔

23

例。

它在Windows的cscript.exe上运行。

// 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

假设我们必须基于特定属性按升序对对象列表进行排序,在本示例中,我们不得不基于“ name”属性进行排序,然后下面是所需代码:

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
我想你有错字?返回a [“ name”]。localeCompare(b。[“ name”]); 应该返回a [“ name”]。localeCompare(b [“ name”]); (删除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 } ]

上述方法将汽车阵列的内容复制到一个新的阵列中,然后根据品牌名称按字母顺序对其进行排序。同样,您可以传递其他函数:

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]);
Mark Schultheiss

是的,因为现在没有对数字的反向检查,谢谢,我应该解决这个问题。但是为什么也可以加倍!return reverse ? (a[prop] - b[prop]) * -1 : (a[prop] - b[prop]);
Marcs

1
!!部队类型强制到本地布尔类型值,而不是JavaScript的价值“falsy”的性质,不是严格必要的,但澄清的目的至少对我来说。请注意,当你返回一个值与!!它是相对于原生型与“falsy”值是说原生布尔类型typeof !!undefinedtypeof !!null等回归“布尔”注意,!!" "true不过!!""false(空间,在没有空间字符串),但您可能已经知道了。
Mark Schultheiss
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.