Home > Software engineering >  Sorting an array of letters by order they came out from original string in JavaScript
Sorting an array of letters by order they came out from original string in JavaScript

Time:09-12

I'm currently learning javascript sorting on terminal/console and due to my limited experience, I'm getting stuck figuring this one out... so please, bare with me.

I'm making a function that will return an array containing vowels of a string. The result array's elements is ordered by which character came first. For example:

Suppose I have this string = "Sample Case"

The function should return a result array like this = [a,a,e,e]

Below is my code and right now, what I can do is to extract the vowels with my function:

const prompt = require('prompt-sync')();

const isVowel = (c) => {
    if(c) {
      return ['a', 'e', 'i', 'o', 'u'].indexOf(c.toLowerCase()) !== -1;
    } else {
      return 'string is empty';
    }
};

const sortChar = () => {
    const wordsInput = prompt("Input one line of word(s): ");
    let vowels = wordsInput.split(' ').join('').split('').filter((x) => isVowel(x));
    let consonants = wordsInput.split(' ').join('').split('').filter((x) => !isVowel(x));


    console.log(vowels.sort((a, b) => {
        if(a === b) {
            return 1;
        }
        return 0;
    }))
};

sortChar();

Current output with above code: [a,e,a,e]

How to sort this result array so that the new result is [a,a,e,e]?

Any input will be appreciated, thank you in advance!

CodePudding user response:

Note: if what you're looking for is not sorting vowels lexically (in alphabetic order) but in the order of appearance, localeCompare() doesn't seem to be an appropriate tool. If I missed the whole point, you may safely ignore this answer.

To me, sorting is a way too expensive operation for this particular use case. I would rather think of it as filtering out vowels and stacking them in the order of appearance (where Map might come in handy).

const sourceString = 'Sample Case'


const isVowel = char => 
  'aeiouAEIOU'.includes(char)

const stackFilteredVowels = str => { 
  const vowelsMap = [...str.toLowerCase()]
    .reduce((acc, char) => {
      const isCharVowel = isVowel(char)
      
      if(isCharVowel) {
        const vowelOccurence = acc.get(char)
        acc.set(char, (vowelOccurence || 0) 1)
      }
      
      return acc
    }, new Map)

  const stackedVowels = [...vowelsMap.entries()]
    .reduce((acc, [vowel, occurence]) => 
      (acc.push(...Array(occurence).fill(vowel)), acc), [])
    
  return stackedVowels
}

console.log(stackFilteredVowels(sourceString))
.as-console-wrapper{min-height: 100%;}

CodePudding user response:

You could

  • get all vowels,
  • iterate the vowels,
    • check if index for theis vowel exist, if not assign a new index and push an empty array to the result set vowels,
    • push vowel to the according array,
  • get flat array,
  • return this array.

function orderVowels(string) {
    const
        indices = {},
        vowels = [];
    
    for (const v of string.match(/[aeiou]/ig)) {
        if (!(v in indices)) {
            indices[v] = vowels.length;
            vowels.push([]);
        }
        vowels[indices[v]].push(v);
    }
    return vowels.flat();
}

console.log(orderVowels("Sample Case"));

CodePudding user response:

const isVowel = (c) => !c ? 'string is empty' : ['a', 'e', 'i', 'o', 'u'].includes(c);

const sortChar = () => {
   const wordsInput = "Input one line of word(s): ";
   const vowels = [...wordsInput].filter(char => isVowel(char) && char.match(/\w/));
   const consonants = [...wordsInput].filter(char => !isVowel(char) && char.match(/\w/));


   console.log({
      vowelsSorted: vowels.sort((a, b) => new Intl.Collator('en').compare(a, b)),
      consonantsSorted: consonants.sort((a, b) => new Intl.Collator('en').compare(a, b))
   })
}
   ;

sortChar();

CodePudding user response:

Let's simplify this. Spread the string into an array and filter the consonants with isVowel. Sort using localeCompare

const isVowel = c => `aeiou`.indexOf((c || ``).toLowerCase()) > -1;
//                                    ^ use empty string if !c
const sortChar = words => {
    return [...words].filter( chr => isVowel(chr) )
//          ^ spread into array
//                   ^ filter delivers array
      .sort( (a, b) => a.localeCompare(b) )
//                       ^ sort using localeCompare  
      .join(``);
};

console.log(sortChar(`As said: input one line of word(s)`));

  • Related