Soy nuevo en javascript y actualmente uso una matriz de objetos
var arrOfObj = [{name: 'eve'},{name: 'eve'},{name:'john'}, {name:'john'}{name:'john'},{name:'mon'},{name:'mon'}, {name:'paul'},{name:'paul'},{name:'paul'}];lo que quiero es colocar todos los objetos que tienen el valor 'paul' para que estén después del valor 'eve'
var arrOfObj = [{name: 'eve'},{name: 'eve'},{name:'paul'}, {name:'paul'}{name:'paul'},{name:'mon'},{name:'mon'}, {name:'john'},{name:'john'},{name:'john'}];Un posible enfoque era usar Array.prototype.sort con una combinación de una función de comparación personalizada (específica de OP) y funciones de comparación de ayuda donde estas últimas resuelven la tarea de asegurar un orden de clasificación ascendente de la manera más genérica posible utilizando también localeCompare para argumentos de tipo cadena.
Editar según el comentario de Teemu
Nota ... por favor, OP tenga en cuenta eso...
"Con un par de diez mil nombres, esto será muy lento. – Teemu"
var arrOfObj = [ { name: 'mon' }, { name: 'paul' }, { name: 'john' }, { name: 'paul' }, { name: 'mon' }, { name: 'eve' }, { name: 'eve' }, { name: 'john' }, { name: 'paul' }, { name: 'john' }, ]; // OP ... what i want is to place all the objects // having value 'paul' to be after value 'eve'. function defaultCompareAscending(a, b) { return ((a < b) && -1) || ((a > b) && 1) || 0; } function compareAscending(a, b) { return (a.localeCompare && b.localeCompare) ? a.localeCompare(b) : defaultCompareAscending(a, b); } console.log( "shallow copy sorted ascending by name ...", [...arrOfObj] .sort((a, b) => compareAscending(a.name, b.name)) ); console.log( "shallow copy sorted to the OP's conditions ...", [...arrOfObj] .sort(({ name: aName }, { name: bName}) => { aName = aName.toLowerCase(); bName = bName.toLowerCase(); return ( (aName === 'paul' && bName === 'eve') && 1 ) || ( (aName === 'eve' && bName === 'paul') && -1 ) || ( aName === 'paul' && -1 ) || ( bName === 'paul' && 1 ) || compareAscending(aName, bName); }) ); console.log( "unsorted original `arrOfObj` reference ...", { arrOfObj } ); .as-console-wrapper { min-height: 100%!important; top: 0; }Un método parametrizable sería como el siguiente, también es adecuado para arreglos grandes.
const arrOfObj = [ {name: 'eve'}, {name: 'eve'}, {name: 'john'}, {name: 'john'}, {name: 'john'}, {name: 'tom'}, {name: 'tom'}, {name: 'paul'}, {name: 'paul'}, {name: 'paul'} ]; function moveAfter(source, target, array) { if (!array.find(({name}) => name === source)) {return array;} // Quit, no source found if (!array.find(({name}) => name === target)) {return array;} // Quit, no target found const from = array.findIndex(({name}) => name === source), count = array.reduce((acc, {name}, index) => name === source ? index : acc, -1) - from + 1, values = array.splice(from, count), to = array.reduce((acc, {name}, index) => name === target ? index : acc, -1) + 1; array.splice(to, 0, ...values); return array; } console.log(moveAfter('paul', 'eve', arrOfObj));El código "mueve pauls after eves in arrOfObj" en su lugar. Y también eves after pauls, o cualquier otro nombre que se pase, siempre que los objetos de nombre estén agrupados por los nombres, y ambos nombres estén presentes en la matriz; si no, la función no hace nada.
La función primero busca el primer índice del parámetro 1, luego el último índice del mismo, haciendo que la longitud del splice corte los objetos de nombre. La posición donde comenzar a agregar el grupo movido es el último índice del parámetro 2. El primer splice luego corta los nombres para moverlos de la matriz, y el segundo splice inserta los valores en el lugar correcto. El aspecto complejo reduce s emula el método "Array.findLastIndex`, que actualmente no existe en JS.
De esta manera, la matriz se reindexa solo dos veces, no se necesita una clasificación costosa en tiempo, por lo tanto, el algoritmo también se puede usar con matrices grandes.
Puede probar el código con otros parámetros en jsFiddle .
Le propongo que maneje manualmente la matriz sin recurrir a la función de sort porque no veo ninguna lógica de clasificación general en su solicitud.
Lo que puede hacer es encontrar los pauls, eliminarlos de la matriz, luego encontrar los eves e insertar los pauls eliminados justo después de ellos.
La solución a continuación asume que, tal como mencionó, todos los objetos con el mismo nombre están uno al lado del otro y no están dispersos en la matriz.
const arrOfObj = [ { name: 'eve' }, { name: 'eve' }, { name:'john' }, { name:'john' }, { name:'john' }, { name:'tom' }, { name:'tom' }, { name:'paul' }, { name:'paul' }, { name:'paul' } ]; // get first and last indexes of paul const firstPaulIndex = arrOfObj.findIndex(({ name }) => (name === 'paul')); const lastPaulIndex = arrOfObj.length - 1 - arrOfObj.slice().reverse().findIndex(({ name }) => (name === 'paul')); // remove the pauls from the array const splicedPauls = arrOfObj.splice(firstPaulIndex, lastPaulIndex - firstPaulIndex + 1); // get the last index of eve after the removal const lastEveIndex = arrOfObj.length - 1 - arrOfObj.slice().reverse().findIndex(({ name }) => (name === 'eve')); // insert the pauls right after the eves arrOfObj.splice(lastEveIndex + 1, 0, ...splicedPauls); console.log(arrOfObj);