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
javascript
arrays
sorting
oop
properties
Konstruktor
źródło
źródło
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
źródło
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");
źródło
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');
źródło
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"}]
źródło
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.źródło
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);
źródło
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; }; };
źródło
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
lubtypeof !!null
itp zwrotny „logiczną” Należy pamiętać, że!!" "
jesttrue
, ale!!""
jestfalse
(przestrzeń, nie ma miejsca w string), ale prawdopodobnie już to wiedziałeś.