Tengo dos matrices y quiero ordenar la primera en función de algunos valores de otra matriz:
const items = [ ['music', ['arr']], ['movies', ['arr']], ['quizes', ['arr']], ['series', ['arr']] ]; const categories = [ { name: "music", priority: 3}, { name: "movies", priority: 2}, { name: "quizes", priority: 5}, { name: "series", priority: 1}, { name: "sports", priority: 4}, ];Quiero ordenar mi primera matriz, por propiedad ' prioridad ' de mi segunda matriz -> de la más grande.
Como esto:
const expectedResult = [ ['quizes', ['arr']], ['music', ['arr']] ['movies', ['arr']], ['series', ['arr']], ];Esto es lo que probé pero sin éxito.
const sorted = items.sort((a,b) => { const [aKey, aVal] = a; const [bKey, bVal] = b; const prio = categories.filter(c => c.name === aKey)[0]; // not sure how to use this prio return aKey.priority - bKey.priority; })Puede usar el método sort() y verificar la prioridad de las categories
const items = [ ['music', ['arr']], ['movies', ['arr']], ['quizes', ['arr']], ['series', ['arr']], ]; const categories = [ { name: 'music', priority: 3 }, { name: 'movies', priority: 2 }, { name: 'quizes', priority: 5 }, { name: 'series', priority: 1 }, { name: 'sports', priority: 4 }, ]; const result = items.sort(([a], [b]) => { const aPriority = categories.find(({ name }) => name === a).priority; const bPriority = categories.find(({ name }) => name === b).priority; return bPriority - aPriority; }); console.log(result);Estabas muy cerca, solo necesitabas tomar la prioridad de b (y también usar la propiedad de priority ). find en lugar de filter es una buena opción:
const sorted = items.sort((a,b) => { const [aKey] = a; const [bKey] = b; const aPriority = categories.find(cat => cat.name === aKey).priority; const bPriority = categories.find(cat => cat.name === bKey).priority; return bPriority - aPriority; });Ejemplo en vivo
const items = [ ["music", ["arr"]], ["movies", ["arr"]], ["quizes", ["arr"]], ["series", ["arr"]] ]; const categories = [ { name: "music", priority: 3}, { name: "movies", priority: 2}, { name: "quizes", priority: 5}, { name: "series", priority: 1}, { name: "sports", priority: 4}, ]; const sorted = items.sort((a,b) => { const [aKey] = a; const [bKey] = b; const aPriority = categories.find(cat => cat.name === aKey).priority; const bPriority = categories.find(cat => cat.name === bKey).priority; return bPriority - aPriority; }); console.log(sorted); .as-console-wrapper { max-height: 100% !important; } Pero recorrer repetidamente ese conjunto de categorías no es una buena idea si items son largos. En su lugar, haga un Map de clave a prioridad, luego use eso:
const catPriorityMap = new Map(categories.map(({name, priority}) => [name, priority])); const sorted = items.sort((a,b) => { const [aKey] = a; const [bKey] = b; const aPriority = catPriorityMap.get(aKey); const bPriority = catPriorityMap.get(bKey); return bPriority - aPriority; });Ejemplo en vivo
const items = [ ["music", ["arr"]], ["movies", ["arr"]], ["quizes", ["arr"]], ["series", ["arr"]] ]; const categories = [ { name: "music", priority: 3}, { name: "movies", priority: 2}, { name: "quizes", priority: 5}, { name: "series", priority: 1}, { name: "sports", priority: 4}, ]; const catPriorityMap = new Map(categories.map(({name, priority}) => [name, priority])); const sorted = items.sort((a,b) => { const [aKey] = a; const [bKey] = b; const aPriority = catPriorityMap.get(aKey); const bPriority = catPriorityMap.get(bKey); return bPriority - aPriority; }); console.log(sorted); .as-console-wrapper { max-height: 100% !important; } La búsqueda en un Map se realiza en tiempo sublineal, mientras que la búsqueda de algo en una matriz se realiza en tiempo lineal.
Realmente no desea utilizar find() o filter() dentro del método de clasificación porque es costoso. En cada iteración, está buscando los datos en la matriz. Así que estás dando muchas vueltas. Hay mejores formas de obtener el índice.
Lo más fácil es hacer un objeto de búsqueda para que no tenga que buscar la otra matriz una y otra vez para encontrar una coincidencia. Entonces, si puede cambiar las categorías de un objeto desde el principio, le hará la vida mucho más fácil.
En la clasificación, agregué el valor máximo en caso de que la clave no esté definida. Ahora, esto sería contraproducente si tuviera un valor de cero, ya que es solo una verificación veraz.
const items = [ ['music', ['arr']], ['movies', ['arr']], ['quizes', ['arr']], ['series', ['arr']] ]; const categories = { music: 3, movies: 2, quizes: 5, series: 1, sports: 4, }; items.sort(([keyA], [keyB]) => (categories[keyA] || Number.MAX_VALUE) - (categories[keyB] || Number.MAX_VALUE)); console.log(items);Si no puede hacer que el objeto se vea así y tiene que usar la matriz, puede convertirlo de la matriz a un objeto. Eso se puede hacer de varias maneras. Me gusta usar reducir.
const items = [ ['music', ['arr']], ['movies', ['arr']], ['quizes', ['arr']], ['series', ['arr']] ]; const categories = [ { name: "music", priority: 3}, { name: "movies", priority: 2}, { name: "quizes", priority: 5}, { name: "series", priority: 1}, { name: "sports", priority: 4}, ]; const lookup = categories.reduce((acc, obj) => ({...acc, [obj.name]: obj.priority}), {}); items.sort(([keyA], [keyB]) => (lookup[keyA] || Number.MAX_VALUE) - (lookup[keyB] || Number.MAX_VALUE)); console.log(items);Ahora, si está seguro de que todas las claves existirán en las categorías, puede eliminar el valor máximo
items.sort(([keyA], [keyB]) => lookup[keyA] - lookup[keyB];