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,
- check if index for theis vowel exist, if not assign a new index and push an empty array to the result set
- 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)`));