Zero Gear
Zero Gear

Reputation: 53

Sorting an array of letters by order they came out from original string in JavaScript

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!

Upvotes: 1

Views: 352

Answers (4)

Yevhen Horbunkov
Yevhen Horbunkov

Reputation: 15530

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%;}

Upvotes: 1

Nina Scholz
Nina Scholz

Reputation: 386624

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"));

Upvotes: 1

KooiInc
KooiInc

Reputation: 122906

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)`));

Upvotes: 0

Michael Lampu
Michael Lampu

Reputation: 161

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();

Upvotes: 0

Related Questions