diff --git a/src/js/wordManagement.js b/src/js/wordManagement.js index 5974149..db36044 100644 --- a/src/js/wordManagement.js +++ b/src/js/wordManagement.js @@ -35,57 +35,65 @@ export function sortWords(render) { const { alphabeticalOrder } = window.currentDictionary; const sortBy = sortByDefinition ? 'definition' : 'name'; - const ordering = {}; // map for efficient lookup of sortIndex - for (let i = 0; i < alphabeticalOrder.length; i++) { - ordering[alphabeticalOrder[i]] = i; - } - window.currentDictionary.words.sort((wordA, wordB) => { - if (wordA[sortBy] === wordB[sortBy]) return 0; - - const aLetters = wordA[sortBy].split(''); - const bLetters = wordB[sortBy].split(''); - - for (let i = 0; i < aLetters.length; i++) { - const a = aLetters[i]; - if (ordering.hasOwnProperty(a)) { // if a is in the alphabet... - if (typeof bLetters[i] !== 'undefined') { // and if wordB has a letter at the same position... - const b = bLetters[i]; - if (ordering.hasOwnProperty(b)) { // and b is in the alphabet then compare the letters - const aIndex = ordering[a]; - const bIndex = ordering[b]; - if (aIndex === bIndex) { // If the letters are the same, then... - // If wordA is shorter than wordB and this is wordA's last letter, then sort a first; - if (aLetters.length < bLetters.length && i == aLetters.length - 1) return -1; - continue; // Otherwise if it is the same letter, check the next letter - } - return aIndex - bIndex; // If different and both in alphabet, compare alphabetical order - } - } else { - return 1; // If b is shorter than a after looping, then sort a after - } - } else if (ordering.hasOwnProperty(bLetters[i])) { - return 1; // If a is not in the alphabet but b is, sort a after - } else { - if (typeof bLetters[i] !== 'undefined') { // and if wordB has a letter at the same position... - const b = bLetters[i]; - if (removeDiacritics(a).toLowerCase() === removeDiacritics(b).toLowerCase()) { - if (aLetters.length < bLetters.length && i == aLetters.length - 1) return -1; - continue; - } - return removeDiacritics(a).toLowerCase() > removeDiacritics(b).toLowerCase() ? 1 : -1; - } else { - return 1; // If b is shorter than a after looping, then sort a after - } - } - } - - console.log('done looping, comparing normally:', wordA[sortBy], wordB[sortBy]); - - // If after looping, the alphabet is still different, just compare the words alphabetically. - if (removeDiacritics(wordA[sortBy]).toLowerCase() === removeDiacritics(wordB[sortBy]).toLowerCase()) return 0; - return removeDiacritics(wordA[sortBy]).toLowerCase() > removeDiacritics(wordB[sortBy]).toLowerCase() ? 1 : -1; + // Sort normally first + return wordA[sortBy].localeCompare(wordB[sortBy], 'en', { sensitivity: 'base' }); // This is the smart way to do the below! + // if (removeDiacritics(wordA[sortBy]).toLowerCase() === removeDiacritics(wordB[sortBy]).toLowerCase()) return 0; + // return removeDiacritics(wordA[sortBy]).toLowerCase() > removeDiacritics(wordB[sortBy]).toLowerCase() ? 1 : -1; }); + + if (alphabeticalOrder.length > 0) { + // If there's an alphabetical order specified, sort by that after! Any letters not in the alphabet will be unsorted, keeping them in ASCII order + const ordering = {}; // map for efficient lookup of sortIndex + for (let i = 0; i < alphabeticalOrder.length; i++) { + ordering[alphabeticalOrder[i]] = i + 1; // Add 1 to prevent 0 from resolving to false + } + + window.currentDictionary.words.sort((wordA, wordB) => { + // console.log(alphabeticalOrder, ordering); + // console.log('comparing:', wordA[sortBy], wordB[sortBy]); + if (wordA[sortBy] === wordB[sortBy]) return 0; + + const aLetters = wordA[sortBy].split(''); + const bLetters = wordB[sortBy].split(''); + + for (let i = 0; i < aLetters.length; i++) { + const a = aLetters[i]; + const b = bLetters[i]; + // console.log('comparing letters', a, b); + if (!b) { + // console.log('no b, ', wordA[sortBy], 'is longer than', wordB[sortBy]); + return 1; + } + if (!ordering[a] && !ordering[b]) { + // console.log('a and b not in dictionary:', a, b, 'continuing to the next letter'); + continue; + } + if (!ordering[a]) { + // console.log('a is not in dictionary:', a, 'moving back:', wordA[sortBy]); + return 1; + } + if (!ordering[b]) { + // console.log('b is not in dictionary:', b, 'moving forward:', wordA[sortBy]); + return -1; + } + if (ordering[a] === ordering[b]) { + // console.log('letters are the same order:', a, b); + if (aLetters.length < bLetters.length && i === aLetters.length - 1) { + // console.log(a, 'is shorter than', b); + return -1; + } + // console.log(a, 'is the same as', b, 'continuing to the next letter'); + continue; + } + // console.log('comparing order:', a, b, 'result:', ordering[a] - ordering[b]); + return ordering[a] - ordering[b]; + } + + // console.log('all of the letters were dumb, no sort'); + return 0; + }); + } saveDictionary(false);