Cách triển khai tình huống sau chỉ sử dụng Javascript:
- Tạo một đối tượng ô tô với các thuộc tính (tốc độ tối đa, thương hiệu, v.v.)
- Sắp xếp danh sách xe ô tô theo thứ tự của các thuộc tính đó
Cách triển khai tình huống sau chỉ sử dụng Javascript:
Câu trả lời:
javascript có hàm sắp xếp có thể nhận một hàm khác làm tham số - hàm thứ hai đó được sử dụng để so sánh hai phần tử.
Thí dụ:
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
được rồi, từ nhận xét của bạn, tôi thấy rằng bạn đang sử dụng từ 'sắp xếp' theo nghĩa sai. Trong lập trình "sort" có nghĩa là "sắp xếp mọi thứ theo một thứ tự nhất định", không phải "sắp xếp mọi thứ theo nhóm". Cách sau đơn giản hơn nhiều - đây chỉ là cách bạn "sắp xếp" mọi thứ trong thế giới thực
a.someProp - b.someProp
) sắp xếp từ thấp nhất đến cao nhất và ngược lại ( b.someProp - a.someProp
) sắp xếp từ cao nhất đến thấp nhất. Về cơ bản, nếu hàm trả về nhỏ hơn 0, a đứng trước b.
Thí dụ.
Điều này chạy trên cscript.exe, trên 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");
Bạn cũng có thể tạo một bộ phân loại chung.
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");
Tôi đã viết hàm đơn giản này cho chính mình:
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);
}
ví dụ bạn có danh sách các xe:
var cars= [{brand: 'audi', speed: 240}, {brand: 'fiat', speed: 190}];
var carsSortedByBrand = sortObj(cars, 'brand');
var carsSortedBySpeed = sortObj(cars, 'speed');
Giả sử chúng ta phải sắp xếp danh sách các đối tượng theo thứ tự tăng dần dựa trên một thuộc tính cụ thể, trong ví dụ này giả sử chúng ta phải sắp xếp dựa trên thuộc tính "name", sau đó dưới đây là mã bắt buộc:
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"}]
Với các hàm mũi tên của ES6, nó sẽ như thế này:
//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()
có thể chấp nhận một hàm so sánh (ở đây tôi đã sử dụng ký hiệu mũi tên, nhưng các hàm thông thường hoạt động giống nhau):
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 } ]
Cách tiếp cận trên sao chép nội dung của mảng ô tô vào một mảng mới và sắp xếp theo thứ tự bảng chữ cái dựa trên tên thương hiệu. Tương tự, bạn có thể chuyển một hàm khác:
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 } ]
Nếu bạn không nhớ việc thay đổi mảng ban đầu cars.sort(comparatorFunction)
sẽ thực hiện được mẹo.
Dưới đây là một ví dụ ngắn gọn, tạo và mảng các đối tượng và sắp xếp theo số hoặc theo bảng chữ cái:
// 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);
Một phiên bản của giải pháp Cheeso với phân loại ngược, tôi cũng đã loại bỏ các biểu thức bậc ba vì thiếu rõ ràng (nhưng đây là sở thích cá nhân).
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]);
!
điều này cũng tốt:return reverse ? (a[prop] - b[prop]) * -1 : (a[prop] - b[prop]);
!!
lực lượng kiểu ép buộc một giá trị kiểu boolean bản địa như trái ngược với "falsy" bản chất của giá trị JavaScript, không cần đúng nhưng làm rõ mục đích ít nhất đối với tôi. Lưu ý rằng khi bạn trả lại một giá trị với !!
nó là một loại Boolean có nguồn gốc như trái ngược với một loại bản địa với một giá trị "falsy" mà là để nói rằng typeof !!undefined
hay typeof !!null
, vv trở lại "boolean" Lưu ý rằng !!" "
là true
nhưng !!""
là false
(không gian, không gian trong string) nhưng bạn có thể đã biết điều đó.