如何仅使用Javascript实现以下场景:
- 创建一个带有属性(最高速度、品牌等)的汽车对象
- 按照这些属性对汽车列表进行排序
如何仅使用Javascript实现以下场景:
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”这个词。在编程中,“sort”表示“按照一定的顺序排列物品”,而不是“将物品分组排列”。后者要简单得多 - 这就是你在现实世界中“排序”物品的方法
a.someProp - b.someProp
表示从最低到最高排序,而反过来的表达式 b.someProp - a.someProp
表示从最高到最低排序。基本上,如果函数返回小于0的值,则a会排在b之前。 - user56reinstatemonica8示例。
这在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");
我为自己写了这个简单的函数:
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');
>
和<
操作符进行值比较就足以处理数字和字符串属性(无需typeof
检查)。 - S.Serpooshan这是一个简短的示例,创建了一个对象数组,并按数字或字母顺序排序:
// 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);
>
和<
运算符比较值就足以处理数字和字符串属性了!所以第二个sort
示例总是有效的。此外,我们可以添加一些等于情况的条件来微调代码性能,以避免不必要的重新定位:(a,b) =>(a.brand> b.brand)?1:(a.brand <b.brand)?-1:0
。 - S.Serpooshan假设我们需要根据特定属性按升序对对象列表进行排序,在本例中,我们要按“名称”属性排序,那么以下是所需的代码:
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"}]
使用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)
可以解决问题。
这是一个带有逆向排序的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;
};
};
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!!
强制类型转换为本地布尔类型值,而不是 JavaScript 值的“假”性质,虽然不是严格必需的,但至少对我来说可以澄清目的。请注意,当您使用 !!
返回一个值时,它是本地布尔类型,而不是具有“假”值的本地类型,也就是说,typeof !!undefined
或 typeof !!null
等返回 "boolean"。请注意,!!" "
是 true
,但 !!""
是 false
(字符串中有空格和没有空格),但您可能已经知道了这一点。 - Mark Schultheiss
cars.sort((a, b) =>
…)
,其中a.prop
和b.prop
分别表示两个待排序对象的属性。a.prop - b.prop
用于数字排序,a.prop.localeCompare(b.prop)
用于字典序排序,(b.prop < a.prop) - (a.prop < b.prop)
用于通用排序。如果要降序排列而不是升序,则取相反数(例如,使用b.prop - a.prop
而不是a.prop - b.prop
)。要按多个属性排序,请使用||
链接其他排序方法,例如:b.someNumber - a.someNumber || a.someString.localeCompare(b.someString)
。 - Sebastian Simona[0] - b[0]
。最后,如果您想对对象的属性本身进行排序,请参见按键排序JavaScript对象。 - Sebastian Simon