Come implementare il seguente scenario utilizzando solo Javascript:
- Crea un oggetto auto con proprietà (velocità massima, marca, ecc.)
- Ordina un elenco di auto ordinate in base a tali proprietà
Come implementare il seguente scenario utilizzando solo Javascript:
Risposte:
javascript ha la funzione di ordinamento che può prendere un'altra funzione come parametro - quella seconda funzione viene utilizzata per confrontare due elementi.
Esempio:
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, dal tuo commento vedo che stai usando la parola "sort" in un senso sbagliato. Nella programmazione "ordinare" significa "mettere le cose in un certo ordine", non "organizzare le cose in gruppi". Quest'ultimo è molto più semplice: è così che "ordinate" le cose nel mondo reale
a.someProp - b.someProp
) ordina dal più basso al più alto e viceversa ( b.someProp - a.someProp
) ordina dal più alto al più basso. Fondamentalmente, se la funzione restituisce meno di 0, a viene prima di b.
Esempio.
Funziona su cscript.exe, su 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");
Puoi anche creare uno smistatore generale.
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");
Ho scritto questa semplice funzione per me stesso:
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);
}
ad esempio hai un elenco di auto:
var cars= [{brand: 'audi', speed: 240}, {brand: 'fiat', speed: 190}];
var carsSortedByBrand = sortObj(cars, 'brand');
var carsSortedBySpeed = sortObj(cars, 'speed');
Supponiamo di dover ordinare un elenco di oggetti in ordine crescente in base a una particolare proprietà, in questo esempio diciamo di dover ordinare in base alla proprietà "name", quindi di seguito è riportato il codice richiesto:
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"}]
Con le funzioni freccia ES6 sarà così:
//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()
può accettare una funzione di confronto (qui ho usato la notazione a freccia, ma le funzioni ordinarie funzionano allo stesso modo):
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 } ]
L'approccio di cui sopra copia il contenuto dell'array di automobili in uno nuovo e lo ordina alfabeticamente in base ai nomi dei marchi. Allo stesso modo, puoi passare una funzione diversa:
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 } ]
Se non ti dispiace cambiare l'array originale cars.sort(comparatorFunction)
farà il trucco.
Ecco un breve esempio, che crea una serie di oggetti e ordina numericamente o alfabeticamente:
// 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);
Una versione della soluzione Cheeso con inversione di ordinamento, ho anche rimosso le espressioni ternarie per mancanza di chiarezza (ma questo è gusto personale).
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]);
!
va bene anche questo:return reverse ? (a[prop] - b[prop]) * -1 : (a[prop] - b[prop]);
!!
tipo forza la coercizione a un valore di tipo booleano nativo in contrasto con la natura "falsa" del valore JavaScript, non strettamente necessario ma chiarisce lo scopo almeno per me. Nota che quando restituisci un valore con !!
esso è un tipo booleano nativo in contrasto con un tipo nativo con un valore "falso", vale a dire typeof !!undefined
o typeof !!null
ecc. Return "booleano" Nota che !!" "
è true
ma !!""
è false
(spazio, nessuno spazio nel stringa) ma probabilmente lo sapevi già.