llenar - Ordenar una matriz, excepto un elemento en JavaScript
filtros javascript (8)
Alternativamente, puede filtrar los nones y ordenar los otros elementos. Luego concaténalos de vuelta uno al otro al final.
let comparison = [{key: "None", value: "None"}, {key: "Geographical Area", value: "Geographical_Area"}, {key: "Forests", value: "Forests"}, {key: "Barren Unculturable Land", value: "Barren_Unculturable_Land"}, {key: "Land put to Non agricultural use", value: "Land_put_to_Non_agricultural_use"}, {key: "Land Area", value: "Land_Area"}, {key: "Water Area", value: "Water_Area"}, {key: "Culturable Waste", value: "Culturable_Waste"}, {key: "Permanent Pastures", value: "Permanent_Pastures"}, {key: "Land under Tree Crops", value: "Land_under_Tree_Crops"}, {key: "Fallow Land excl Current Fallow", value: "Fallow_Land_excl_Current_Fallow"}, {key: "Current Fallow", value: "Current_Fallow"}, {key: "Total Unculturable Land", value: "Total_Unculturable_Land"}, {key: "Net Sown Area", value: "Net_Sown_Area"}, {key: "Gross Sown Area", value: "Gross_Sown_Area"}, {key: "Cropping Intensity", value: "Cropping_Intensity"}];
let result = comparison
.filter(e => e.key === ''None'')
.concat(
comparison.filter(e => e.key !== ''None'')
.sort((a, b) => a.key.localeCompare(b.key))
);
console.log(result);
Explicación:
let comparison = [{key: "None", value: "None"}, {key: "Geographical Area", value: "Geographical_Area"}, {key: "Forests", value: "Forests"}, {key: "Barren Unculturable Land", value: "Barren_Unculturable_Land"}, {key: "Land put to Non agricultural use", value: "Land_put_to_Non_agricultural_use"}, {key: "Land Area", value: "Land_Area"}, {key: "Water Area", value: "Water_Area"}, {key: "Culturable Waste", value: "Culturable_Waste"}, {key: "Permanent Pastures", value: "Permanent_Pastures"}, {key: "Land under Tree Crops", value: "Land_under_Tree_Crops"}, {key: "Fallow Land excl Current Fallow", value: "Fallow_Land_excl_Current_Fallow"}, {key: "Current Fallow", value: "Current_Fallow"}, {key: "Total Unculturable Land", value: "Total_Unculturable_Land"}, {key: "Net Sown Area", value: "Net_Sown_Area"}, {key: "Gross Sown Area", value: "Gross_Sown_Area"}, {key: "Cropping Intensity", value: "Cropping_Intensity"}];
// fetch all elements with the key ''None''
let nones = comparison.filter(e => e.key === ''None'');
// fetch all elements with the key not ''None''
let others = comparison.filter(e => e.key !== ''None'')
// sort the elements in the array by key
.sort((a, b) => a.key.localeCompare(b.key));
// concatenate the 2 arrays together
let result = nones.concat(others);
console.log(result);
Un poco de crédito a la respuesta de Pac0s . Después de escribir mi solución, vi que básicamente hice una versión funcional de su explicación. Soy demasiado tarde para agregar mi ejemplo a su respuesta porque actualmente es el más votado de los dos.
Tengo una matriz y la estoy ordenando, pero necesito ordenar todo excepto un elemento de mi matriz.
Mi matriz es:
var Comparison = [
{key: "None", value: "None"},
{key:"Geographical Area", value:"Geographical_Area"},
{key:"Forests", value:"Forests"},
{key:"Barren Unculturable Land", value:"Barren_Unculturable_Land"},
{key:"Land put to Non agricultural use", value:"Land_put_to_Non_agricultural_use"},
{key:"Land Area", value:"Land_Area"},
{key:"Water Area", value:"Water_Area"},
{key:"Culturable Waste", value:"Culturable_Waste"},
{key:"Permanent Pastures", value:"Permanent_Pastures"},
{key:"Land under Tree Crops", value:"Land_under_Tree_Crops"},
{key:"Fallow Land excl Current Fallow", value:"Fallow_Land_excl_Current_Fallow"},
{key:"Current Fallow", value:"Current_Fallow"},
{key:"Total Unculturable Land", value:"Total_Unculturable_Land"},
{key:"Net Sown Area", value:"Net_Sown_Area"},
{key:"Gross Sown Area", value:"Gross_Sown_Area"},
{key:"Cropping Intensity", value:"Cropping_Intensity"} ];
Estoy ordenando esta matriz usando este código:
var Comparison_sort = this.Comparison.sort(function (a, b) {
if (a.key < b.key)
return -1;
if (a.key > b.key)
return 1;
return 0;
});
Esto es ordenar mi matriz perfectamente, pero quiero que uno de mis elementos esté en la parte superior, lo que significa que mi elemento Ninguno debe estar en la parte superior y ordenar todos los demás elementos.
Por ejemplo, estoy obteniendo este resultado:
{key: "Barren Unculturable Land", value: "Barren_Unculturable_Land"}
{key: "Cropping Intensity", value: "Cropping_Intensity"}
{key: "Culturable Waste", value: "Culturable_Waste"}
....
{key: "None", value: "None"}
Pero quiero un resultado como este:
{key: "None", value: "None"}
{key: "Barren Unculturable Land", value: "Barren_Unculturable_Land"}
{key: "Cropping Intensity", value: "Cropping_Intensity"}
{key: "Culturable Waste", value: "Culturable_Waste"}
....
Vi una respuesta, Ordenar matriz en TypeScript , pero no pude utilizar esta respuesta a mi problema.
La función <Array>.sort
toma una devolución de llamada como un argumento. Esta devolución de llamada se pasará dos valores. El trabajo de la devolución de llamada es determinar cuál es más grande. Lo hace devolviendo un valor numérico.
Digamos que los argumentos pasados a su devolución de llamada se llaman a
y b
. He marcado los valores que debe devolver su devolución de llamada para cada caso.
-
a < b
Menos de 0 -
a > b
Mayor que 0 -
a = b
Igual a 0
Esto es fácil de recordar porque, para valores numéricos, puede usar a - b
para obtener el valor de retorno deseado.
Ahora, a pesar de que la mayoría de las devoluciones de llamadas a .sort
son muy pequeñas, es posible pasar funciones muy complicadas para satisfacer sus necesidades. En este caso,
- Si
a.key
es None,a < b
- Si
b.key
es None,b < a
- Si no, utiliza nuestro mecanismo de ordenación actual.
Podríamos aprovechar la declaración de return
que sale una vez que se llama. Entonces, implementemos esta función de bala por bala.
Para hacer que nuestro código sea Super Bueno, devolvamos "0" cuando los dos valores son iguales (incluso cuando esos dos valores tienen claves de "Ninguno")
Comparison.sort(function(a, b) {
// Our extra code
if(a.key === b.key) return 0; // Zero (a = b)
if(a.key === "None") return -1; // Negative (a < b)
if(b.key === "None") return 1; // Positive (b < a)
// Old sort
if(a.key < b.key) return -1;
if(b.key < a.key) return 1;
})
Golfing esa solucion
Hay maneras de hacer que la solución sea más corta (y, quizás, más legible), lo cual es importante cuando el código está haciendo tareas simples.
Lo primero que se debe tener en cuenta es que la línea final, if(b.key < a.key) return -1
podría acortarse para return -1;
. Esto se debe a que si a.key < b.key
o b.key = a.key
hubiéramos regresado en una línea anterior.
La segunda cosa a tener en cuenta es que al utilizar la sintaxis ES6 (que podría no ser compatible con navegadores más antiguos, en particular con respecto a Internet Explorer), podemos usar la notación de la función de flecha para la devolución de llamada.
function(a, b) {}
podría convertirse en (a, b) => {}
La tercera cosa a tener en cuenta es que podemos convertir el siguiente bloque de código
if(a.key < b.key) return -1;
if(b.key < a.key) return 1;
dentro
return (b.key < a.key) - (a.key < b.key)
Esto se debe a que la true
se trata como 1
y la false
como 0
cuando se trata de la resta. true - false
es 1 - 0
es 1
, false - true
es 0 - 1
es -1
, y 0 - 0
es 0
. Nunca habrá una situación en la que la true - true
ocurra.
No es sofisticado, pero una forma bastante sencilla de hacer esto es simplemente eliminar el elemento especial, ordenar la matriz e insertar el especial en el índice que desee.
var Comparison = [{ key: "None", value: "None" }, { key: "Geographical Area",value: "Geographical_Area" }, { key: "Forests", value: "Forests" }, { key: "Barren Unculturable Land", value: "Barren_Unculturable_Land" }, { key: "Land put to Non agricultural use", value: "Land_put_to_Non_agricultural_use" }, { key: "Land Area", value: "Land_Area" }, { key: "Water Area", value: "Water_Area" }, { key: "Culturable Waste", value: "Culturable_Waste" }, { key: "Permanent Pastures", value: "Permanent_Pastures" }, { key: "Land under Tree Crops", value: "Land_under_Tree_Crops" }, { key: "Fallow Land excl Current Fallow", value: "Fallow_Land_excl_Current_Fallow" }, { key: "Current Fallow", value: "Current_Fallow" }, { key: "Total Unculturable Land", value: "Total_Unculturable_Land" }, { key: "Net Sown Area", value: "Net_Sown_Area" }, { key: "Gross Sown Area", value: "Gross_Sown_Area" }, { key: "Cropping Intensity", value: "Cropping_Intensity" },];
const idx = Comparison.findIndex(a => a.key === ''None'');
const none = Comparison.splice(idx, 1);
Comparison.sort((a, b) => a.key.localeCompare(b.key));
Comparison.splice(0,0, none[0]);
console.log(Comparison);
Para evitar problemas de elementos especiales especiales o múltiples:
var Comparison = [{ key: "None", value: "None" }, { key: "Geographical Area",value: "Geographical_Area" }, { key: "Forests", value: "Forests" }, { key: "Barren Unculturable Land", value: "Barren_Unculturable_Land" }, { key: "Land put to Non agricultural use", value: "Land_put_to_Non_agricultural_use" }, { key: "Land Area", value: "Land_Area" }, { key: "Water Area", value: "Water_Area" }, { key: "Culturable Waste", value: "Culturable_Waste" }, { key: "Permanent Pastures", value: "Permanent_Pastures" }, { key: "Land under Tree Crops", value: "Land_under_Tree_Crops" }, { key: "Fallow Land excl Current Fallow", value: "Fallow_Land_excl_Current_Fallow" }, { key: "Current Fallow", value: "Current_Fallow" }, { key: "Total Unculturable Land", value: "Total_Unculturable_Land" }, { key: "Net Sown Area", value: "Net_Sown_Area" }, { key: "Gross Sown Area", value: "Gross_Sown_Area" }, { key: "Cropping Intensity", value: "Cropping_Intensity" },];
const obj = Comparison.reduce((acc, a) => {
if (a.key === ''None'') {
acc.f.push(a);
} else {
const idx = acc.s.findIndex(b => b.key.localeCompare(a.key) > 0);
acc.s.splice(idx === -1 ? acc.s.length : idx, 0, a);
}
return acc;
}, { f: [], s: [] });
const res = obj.f.concat(obj.s);
console.log(res);
Puede haber un mejor enfoque, pero esto debería funcionar:
Filtra el valor especial de tu matriz.
Ordena tu matriz sin el valor especial.
Insertar el valor especial de nuevo en la matriz.
¡Para un buen ejemplo de trabajo, vea la respuesta de @Johan Wentholt !
Puede utilizar reduce
para lograr el resultado deseado:
var Comparison = [{key:"Geographical Area", value:"Geographical_Area"}, {key:"Forests", value:"Forests"}, {key:"Barren Unculturable Land", value:"Barren_Unculturable_Land"}, {key: "None", value: "None"}, {key:"Land put to Non agricultural use", value:"Land_put_to_Non_agricultural_use"}, {key:"Land Area", value:"Land_Area"}, {key:"Water Area", value:"Water_Area"}, {key:"Culturable Waste", value:"Culturable_Waste"}, {key:"Permanent Pastures", value:"Permanent_Pastures"}, {key:"Land under Tree Crops", value:"Land_under_Tree_Crops"}, {key:"Fallow Land excl Current Fallow", value:"Fallow_Land_excl_Current_Fallow"}, {key:"Current Fallow", value:"Current_Fallow"}, {key:"Total Unculturable Land", value:"Total_Unculturable_Land"}, {key:"Net Sown Area", value:"Net_Sown_Area"}, {key:"Gross Sown Area", value:"Gross_Sown_Area"}, {key:"Cropping Intensity", value:"Cropping_Intensity"},]
var Comparison_sort = Comparison
.sort((a, b) => a.key.localeCompare(b.key))
.reduce((acc, e) => {
e.key === ''None'' ? acc.unshift(e) : acc.push(e);
return acc;
}, []);
console.log(Comparison_sort);
Ordenar utilizando reduce
versión 2:
let comparison = [{key: "None", value: "None"}, {key: "Geographical Area", value: "Geographical_Area"}, {key: "Forests", value: "Forests"}, {key: "Barren Unculturable Land", value: "Barren_Unculturable_Land"}, {key: "Land put to Non agricultural use", value: "Land_put_to_Non_agricultural_use"}, {key: "Land Area", value: "Land_Area"}, {key: "Water Area", value: "Water_Area"}, {key: "Culturable Waste", value: "Culturable_Waste"}, {key: "Permanent Pastures", value: "Permanent_Pastures"}, {key: "Land under Tree Crops", value: "Land_under_Tree_Crops"}, {key: "Fallow Land excl Current Fallow", value: "Fallow_Land_excl_Current_Fallow"}, {key: "Current Fallow", value: "Current_Fallow"}, {key: "Total Unculturable Land", value: "Total_Unculturable_Land"}, {key: "Net Sown Area", value: "Net_Sown_Area"}, {key: "Gross Sown Area", value: "Gross_Sown_Area"}, {key: "Cropping Intensity", value: "Cropping_Intensity"}];
var {Comparison_sort} = comparison.reduce((acc, obj, idx, arr) => {
obj.key === ''None'' ? acc[''first''].push(obj) : acc[''last''].push(obj)
if (idx === arr.length - 1) (acc[''last''].sort((a, b) => a.key.localeCompare(b.key)), acc[''Comparison_sort''] = [...acc[''first''], ...acc[''last'']])
return acc
}, {first: [], last: [], Comparison_sort: []})
console.log(Comparison_sort);
Simplemente añada un cheque al principio. Si es el objeto ninguno, muévalo al frente sin realizar las comprobaciones.
var Comparison_sort = this.Comparison.sort(function (a, b) {
if (a.key == "None" && a.value == "None")
return -1;
if (b.key == "None" && b.value == "None")
return 1;
if (a.key < b.key)
return -1;
if (a.key > b.key)
return 1;
return 0;
});
Un sencillo de una línea: si alguna de las claves en la función de comparación Array.prototype.sort
es ''Ninguna'', entonces póngala siempre arriba, de lo contrario, haga una comparación básica de las claves con String.prototype.localeCompare()
:
var comparison = [{key: "None", value: "None"}, {key: "Geographical Area", value: "Geographical_Area"}, {key: "Forests", value: "Forests"}, {key: "Barren Unculturable Land", value: "Barren_Unculturable_Land"}, {key: "Land put to Non agricultural use", value: "Land_put_to_Non_agricultural_use"}, {key: "Land Area", value: "Land_Area"}, {key: "Water Area", value: "Water_Area"}, {key: "Culturable Waste", value: "Culturable_Waste"}, {key: "Permanent Pastures", value: "Permanent_Pastures"}, {key: "Land under Tree Crops", value: "Land_under_Tree_Crops"}, {key: "Fallow Land excl Current Fallow", value: "Fallow_Land_excl_Current_Fallow"}, {key: "Current Fallow", value: "Current_Fallow"}, {key: "Total Unculturable Land", value: "Total_Unculturable_Land"}, {key: "Net Sown Area", value: "Net_Sown_Area"}, {key: "Gross Sown Area", value: "Gross_Sown_Area"}, {key: "Cropping Intensity", value: "Cropping_Intensity"}];
var sorted = comparison.sort((a,b) => a.key === ''None'' ? -1 : b.key === ''None'' ? 1 : a.key.localeCompare(b.key));
console.log(sorted);
var Comparison_sort = this.Comparison.sort(function (a, b) {
if(a.key == b.key) return 0;
if (a.key == ''None'') return -1;
if (b.key == ''None'') return 1;
if (a.key < b.key)
return -1;
if (a.key > b.key)
return 1;
return 0;
});
le dice a "haga una ordenación regular, excepto si la clave es ninguna, lo que significa que debe ir primero".