Comment implémenter le scénario suivant en utilisant uniquement Javascript:
- Créez un objet voiture avec des propriétés (vitesse maximale, marque, etc.)
- Trier une liste de voitures classées par ces propriétés
Comment implémenter le scénario suivant en utilisant uniquement Javascript:
Réponses:
javascript a la fonction de tri qui peut prendre une autre fonction comme paramètre - cette seconde fonction est utilisée pour comparer deux éléments.
Exemple:
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, d'après votre commentaire, je vois que vous utilisez le mot «trier» dans un mauvais sens. Dans la programmation, «trier» signifie «mettre les choses dans un certain ordre», pas «organiser les choses en groupes». Ce dernier est beaucoup plus simple - c'est ainsi que vous «triez» les choses dans le monde réel
a.someProp - b.someProp
) trie du plus bas au plus élevé , et l'inverse ( b.someProp - a.someProp
) trie du plus élevé au plus bas. Fondamentalement, si la fonction renvoie moins de 0, a vient avant b.
Exemple.
Cela fonctionne sur cscript.exe, sous 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");
Vous pouvez également créer un trieur général.
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");
J'ai écrit cette fonction simple pour moi-même:
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);
}
par exemple vous avez une liste de voitures:
var cars= [{brand: 'audi', speed: 240}, {brand: 'fiat', speed: 190}];
var carsSortedByBrand = sortObj(cars, 'brand');
var carsSortedBySpeed = sortObj(cars, 'speed');
Disons que nous devons trier une liste d'objets dans l'ordre croissant en fonction d'une propriété particulière, dans cet exemple, disons que nous devons trier en fonction de la propriété "name", puis ci-dessous est le code requis:
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"}]
Avec les fonctions fléchées ES6, ce sera comme ceci:
//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()
peut accepter une fonction de comparateur (ici j'ai utilisé la notation fléchée, mais les fonctions ordinaires fonctionnent de la même manière):
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'approche ci-dessus copie le contenu du tableau de voitures dans un nouveau et le trie par ordre alphabétique en fonction des noms de marque. De même, vous pouvez passer une fonction différente:
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 } ]
Si cela ne vous dérange pas, la mutation du tableau original cars.sort(comparatorFunction)
fera l'affaire.
Voici un court exemple qui crée un tableau d'objets et les trie par ordre numérique ou alphabétique:
// 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);
Version de la solution Cheeso avec tri inversé, j'ai également supprimé les expressions ternaires par manque de clarté (mais c'est un goût personnel).
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]);
!
c'est bien aussi:return reverse ? (a[prop] - b[prop]) * -1 : (a[prop] - b[prop]);
!!
contrainte de type force à une valeur de type booléen natif par opposition à la nature «falsifiée» de la valeur JavaScript, ce n'est pas strictement nécessaire mais clarifie le but au moins pour moi. Notez que lorsque vous renvoyez une valeur avec !!
elle est un type booléen natif par opposition à un type natif avec une valeur "falsy", c'est-à-dire le typeof !!undefined
ou typeof !!null
etc. retournez "boolean" Notez que !!" "
c'est true
mais !!""
est false
(espace, pas d'espace string) mais vous le saviez probablement déjà.