Tengo la matriz de cadenas que quiero ordenar en un orden personalizado Mi matriz se ve así
["E", "D", "CC", "C", "B", "BB", "BBA", "BBD", "BBE", "BBB", "BBBC", "A", "AA"]
En mi matriz ordenada, quiero mostrar las palabras alfabéticamente, pero las palabras con una gran cantidad de letras continuas deben aparecer primero.
Si más palabras tienen la misma longitud de letra continua, entonces debe considerar la siguiente letra alfabéticamente.
Mi resultado esperado debería verse así
["AA", "A","BBBC", "BBB","BBA", "BBD", "BBE", "BB", "B", "CC", "C", "D", "E"]
Traté de ordenar usando la función sort() predeterminada pero no me dio los resultados esperados. Así que por favor dé sus sugerencias
Primero escribiría una función que compare 2 elementos con las reglas esperadas y devuelva 1 si el primer elemento debe ser el primero, de lo contrario -1, verifique la longitud de los 2 elementos y vea si el más largo comienza con el más pequeño (como en "AAA"
y "A"
)
function myComparer(a, b) { if (a.length < b.length) { if (b.startsWith(a)) { return 1; // a should be after b } } else if (a.length > b.length) { if (a.startsWith(b)) { return -1; // b should be after a } } if (a < b) { return -1; } return 1; } const CompareTester = (a, b) => { if (myComparer(a, b) == -1) { console.log(`"${a}" then "${b}"`); } else { console.log(`"${b}" then "${a}"`); } } const testArr = [ { a: "AAA", b: "A" }, { a: "A", b: "AAA" }, { a: "BBA", b: "BB" }, { a: "A", b: "B" }, { a: "ABC", b: "DEF" }, { a: "ABC", b: "ABCDEF" } ]; for (elem of testArr) { CompareTester(elem.a, elem.b); }
Ahora, puede usar esta función como devolución de llamada para el método .sort()
:
const arr = ["E", "D", "CC", "C", "B", "BB", "BBA", "BBD", "BBE", "BBB", "BBBC", "A", "AA"]; function myComparer(a, b) { if (a.length < b.length) { if (b.startsWith(a)) { return 1; // a should be after b } } else if (a.length > b.length) { if (a.startsWith(b)) { return -1; // b should be after a } } if (a < b) { return -1; } return 1; } arr.sort(myComparer); console.log(arr);
Necesita su propio algoritmo de clasificación personalizado para este tipo de clasificación.
var yourArray = ["E", "D", "CC", "C", "B", "BB", "BBB", "A", "AA"]; // Unsorted Array let customerSort = (arr) => { // This loop is for iterating array for (var i = 0; i < arr.length; i++) { // This loop is for comparing each item of the array with all items in array for (var j = 0; j < arr.length; j++) { // This condition is for sorting array in alphabetical order if (arr[i] < arr[j]) { var x = arr[i]; arr[i] = arr[j]; arr[j] = x; } // This condition is for sorting array in the custom order needed if (arr[i].charAt(0) == arr[j].charAt(0) && arr[i].length > arr[j].length) { var x = arr[i]; arr[i] = arr[j]; arr[j] = x; } } } // Return Sorted Array return arr; } console.log(customerSort(yourArray));
El desafío fue comprender las reglas de clasificación implícitas en la pregunta, pero creo que puedo reafirmar el OP para sugerir que las cadenas deben ordenarse primero por el orden léxico de la primera letra, luego por la longitud de ejecución del primer conjunto de caracteres repetidos , luego por la longitud total de la cadena y, por último, por el orden léxico de los caracteres restantes.
Para exponer esa lógica claramente en la ordenación, este fragmento preprocesa las cadenas de entrada en objetos como:
{ input: "BBBC", firstChar: "B", runLength: 3, fallback: "C", length: 4 }
Si todo eso es correcto, entonces el tipo es simple...
function sortInfo(original) { const firstLetter = original[0]; const length = original.length; let runLength = 0; for (let letter of original) { if (letter === firstLetter) runLength++; else break; } const fallback = original.slice(runLength) return { original, firstLetter, runLength, length, fallback } } let input = ["E", "D", "CC", "C", "B", "BB", "BBA", "BBD", "BBE", "BBB", "BBBC", "A", "AA"]; let sortable = input.map(sortInfo) sortable.sort((a,b) => { if (a.firstLetter !== b.firstLetter) return a.firstLetter.localeCompare(b.firstLetter); if (a.runLength !== b.runLength) return b.runLength - a.runLength; if (a.length !== b.length) return b.length - a.length; return a.fallback.localeCompare(b.fallback); }); console.log(sortable.map(o => o.original))