Jak zaimplementować następujący scenariusz tylko przy użyciu JavaScript:
- Utwórz obiekt samochodu z właściwościami (maksymalna prędkość, marka itp.)
- Sortuj listę samochodów uporządkowaną według tych właściwości
Jak zaimplementować następujący scenariusz tylko przy użyciu JavaScript:
Odpowiedzi:
javascript ma funkcję sortowania, która może przyjąć inną funkcję jako parametr - ta druga funkcja jest używana do porównania dwóch elementów.
Przykład:
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
ok, z twojego komentarza wynika, że używasz słowa „sort” w złym znaczeniu. W programowaniu „sortowanie” oznacza „układanie rzeczy w określonej kolejności”, a nie „układanie rzeczy w grupy”. To drugie jest znacznie prostsze - tak właśnie „sortujesz” rzeczy w prawdziwym świecie
a.someProp - b.someProp
) sortuje od najniższego do najwyższego , a odwrotne ( b.someProp - a.someProp
) sortuje od najwyższego do najniższego. Zasadniczo, jeśli funkcja zwraca mniej niż 0, a występuje przed b.
Przykład.
Działa na cscript.exe w systemie 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");
Możesz także wykonać ogólny sortownik.
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");
Napisałem dla siebie tę prostą funkcję:
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);
}
na przykład masz listę samochodów:
var cars= [{brand: 'audi', speed: 240}, {brand: 'fiat', speed: 190}];
var carsSortedByBrand = sortObj(cars, 'brand');
var carsSortedBySpeed = sortObj(cars, 'speed');
Powiedzmy, że musimy posortować listę obiektów w porządku rosnącym na podstawie określonej właściwości, w tym przykładzie powiedzmy, że musimy posortować według właściwości „name”, a poniżej jest wymagany kod:
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"}]
Z funkcjami strzałkowymi ES6 będzie tak:
//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()
może przyjąć funkcję komparatora (tutaj użyłem notacji strzałkowej, ale zwykłe funkcje działają tak samo):
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 } ]
Powyższe podejście kopiuje zawartość tablicy samochodów do nowej i sortuje ją alfabetycznie na podstawie nazw marek. Podobnie możesz przekazać inną funkcję:
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 } ]
Jeśli nie masz nic przeciwko mutacji oryginalnej tablicy, cars.sort(comparatorFunction)
wystarczy.
Oto krótki przykład, który tworzy tablicę obiektów i sortuje numerycznie lub alfabetycznie:
// 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);
Wersja rozwiązania Cheeso z odwrotnym sortowaniem, usunąłem również trójskładnikowe wyrażenia dla niejasności (ale to jest osobisty gust).
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]);
!
to też jest w porządku:return reverse ? (a[prop] - b[prop]) * -1 : (a[prop] - b[prop]);
!!
Rodzaj sił przymusu z natywną wartość logiczna typu, w przeciwieństwie do „natury” falsy wartości JavaScript, ale nie jest to bezwzględnie konieczne wyjaśnia zastosowania przynajmniej dla mnie. Należy pamiętać, że po powrocie z wartości !!
jest to rodzimy typ Boolean w przeciwieństwie do natywnego typu z „falsy” wartości, która ma powiedzieć typeof !!undefined
lub typeof !!null
itp zwrotny „logiczną” Należy pamiętać, że !!" "
jest true
, ale !!""
jest false
(przestrzeń, nie ma miejsca w string), ale prawdopodobnie już to wiedziałeś.