Como implementar o seguinte cenário usando apenas Javascript:
- Crie um objeto de carro com propriedades (velocidade máxima, marca, etc.)
- Classifique uma lista de carros ordenados por essas propriedades
javascript
arrays
sorting
oop
properties
Construtor
fonte
fonte
Respostas:
javascript tem a função de classificação que pode ter outra função como parâmetro - essa segunda função é usada para comparar dois elementos.
Exemplo:
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, pelo seu comentário, vejo que você está usando a palavra 'classificar' no sentido errado. Na programação, "classificar" significa "colocar as coisas em uma certa ordem", não "organizar as coisas em grupos". O último é muito mais simples - é assim que você "classifica" as coisas no mundo real
fonte
a.someProp - b.someProp
) classifica do mais baixo para o mais alto , e reverse (b.someProp - a.someProp
) classifica do mais alto para o mais baixo. Basicamente, se a função retornar menos que 0, a vem antes de b.Exemplo.
Isso é executado em cscript.exe, no 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");
Você também pode fazer uma classificação geral.
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");
fonte
Eu escrevi esta função simples para mim:
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 exemplo, você tem uma lista de carros:
var cars= [{brand: 'audi', speed: 240}, {brand: 'fiat', speed: 190}]; var carsSortedByBrand = sortObj(cars, 'brand'); var carsSortedBySpeed = sortObj(cars, 'speed');
fonte
Digamos que temos que classificar uma lista de objetos em ordem crescente com base em uma propriedade particular, neste exemplo, digamos que temos que classificar com base na propriedade "nome", abaixo está o código necessário:
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"}]
fonte
Com as funções de seta ES6 , será assim:
//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()
pode aceitar uma função de comparador (aqui eu usei a notação de seta, mas as funções comuns funcionam da mesma forma):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 } ]
A abordagem acima copia o conteúdo da matriz de carros em uma nova e classifica em ordem alfabética com base nos nomes das marcas. Da mesma forma, você pode passar uma função 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 } ]
Se você não se importar em mudar a matriz original
cars.sort(comparatorFunction)
, isso resolverá o problema.fonte
Aqui está um pequeno exemplo, que cria uma matriz de objetos e classifica numericamente ou 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);
fonte
Uma versão da solução Cheeso com classificação reversa, também removi as expressões ternárias por falta de clareza (mas este é o gosto pessoal).
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; }; };
fonte
return !!reverse ? (a[prop] - b[prop]) * -1 : (a[prop] - b[prop]);
!
também está bom:return reverse ? (a[prop] - b[prop]) * -1 : (a[prop] - b[prop]);
!!
forças de coerção de tipo para um valor de tipo booleano nativo em oposição à natureza "falsa" do valor JavaScript, não estritamente necessário, mas esclarece o propósito pelo menos para mim. Observe que, quando você retorna um valor com!!
ele, é um tipo booleano nativo em oposição a um tipo nativo com um valor "falso", que quer dizer otypeof !!undefined
outypeof !!null
etc. retorna "booleano" Observe que!!" "
étrue
mas!!""
éfalse
(espaço, nenhum espaço no string), mas você provavelmente já sabia disso.