Cómo implementar el siguiente escenario usando solo Javascript:
- Crea un objeto de coche con propiedades (velocidad máxima, marca, etc.)
- Ordenar una lista de autos ordenados por esas propiedades
javascript
arrays
sorting
oop
properties
Constructor
fuente
fuente
Respuestas:
javascript tiene la función de clasificación que puede tomar otra función como parámetro; esa segunda función se usa para comparar dos elementos.
Ejemplo:
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, por tu comentario veo que estás usando la palabra 'ordenar' en un sentido equivocado. En programación, "ordenar" significa "poner las cosas en un cierto orden", no "organizar las cosas en grupos". Esto último es mucho más simple: así es como se "clasifican" las cosas en el mundo real.
fuente
a.someProp - b.someProp
) ordena de menor a mayor , y el inverso (b.someProp - a.someProp
) ordena de mayor a menor. Básicamente, si la función devuelve menos de 0, a viene antes de b.Ejemplo.
Esto se ejecuta en cscript.exe, en 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");
También puedes hacer un clasificador general.
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");
fuente
He escrito esta función simple para mí:
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); }
por ejemplo, tienes una lista de coches:
var cars= [{brand: 'audi', speed: 240}, {brand: 'fiat', speed: 190}]; var carsSortedByBrand = sortObj(cars, 'brand'); var carsSortedBySpeed = sortObj(cars, 'speed');
fuente
Digamos que tenemos que ordenar una lista de objetos en orden ascendente en función de una propiedad en particular, en este ejemplo, digamos que tenemos que ordenar en función de la propiedad "nombre", luego a continuación se muestra el código requerido:
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"}]
fuente
Con las funciones de flecha de ES6 será así:
//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()
puede aceptar una función de comparación (aquí usé notación de flecha, pero las funciones ordinarias funcionan igual):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 } ]
El enfoque anterior copia el contenido de la matriz de coches en uno nuevo y lo ordena alfabéticamente según los nombres de las marcas. Del mismo modo, puede pasar una función diferente:
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 no le importa mutar la matriz original,
cars.sort(comparatorFunction)
será suficiente.fuente
Aquí hay un breve ejemplo, que crea una matriz de objetos y los ordena numérica o alfabéticamente:
// 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);
fuente
Una versión de la solución Cheeso con clasificación inversa, también eliminé las expresiones ternarias por falta de claridad (pero esto es un gusto personal).
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; }; };
fuente
return !!reverse ? (a[prop] - b[prop]) * -1 : (a[prop] - b[prop]);
!
esto también está bien:return reverse ? (a[prop] - b[prop]) * -1 : (a[prop] - b[prop]);
!!
fuerzas de tipo coerción a un valor de tipo booleano nativo en oposición a la naturaleza "falsa" del valor de JavaScript, no es estrictamente necesario pero aclara el propósito al menos para mí. Tenga en cuenta que cuando devuelve un valor con!!
él, es un tipo booleano nativo en lugar de un tipo nativo con un valor "falso", es decir,typeof !!undefined
o,typeof !!null
etc., devuelve "booleano". Tenga en cuenta que!!" "
estrue
pero!!""
esfalse
(espacio, sin espacio en el string) pero probablemente ya lo sabías.