Reputation: 69
I Have array like
['Ajith', 'Arya', 'Akalya', 'Akila', 'Bharath', 'Bhakya', 'Kavitha', 'Kamal', 'Bavi']
I want ouptut like
['A',
'Ajith',
'Arya',
'Akila',
'B',
'Bharath',
'Bhakya',
'Bavi',
'k',
'Kamal']
how can i acheive this in javascript Help me and thanks advance
Upvotes: 0
Views: 196
Reputation: 8087
let d=["Ajith","Arya","Akalya","Akila",
"Bharath","Bhakya","Kavitha","Kamal","Bavi"].sort()
let r=[...new Set(d.map(([c])=>c))].flatMap(c=>[c, ...d.filter(([i])=>i==c)])
console.log(r)
or:
let d = ["Ajith","Arya","Akalya","Akila",
"Bharath","Bhakya","Kavitha","Kamal","Bavi"].sort()
let r = Object.values(d.map(s=>
[s.charAt(0),s]).reduce((c,[a,b])=>((c[a]??=[a]).push(b),c),{})).flat()
console.log(r)
Upvotes: 1
Reputation: 2861
Several good answers are already here. This one may be a little bit simpler:
const arr = ['Ajith', 'Arya', 'Akalya', 'Akila', 'Bharath', 'Bhakya', 'Kavitha', 'Kamal', 'Bavi'].sort();
for(let i = arr.length -1; i>=0; i--) {
if(i === 0 || arr[i][0] !== arr[i-1][0]) arr.splice(i,0, arr[i][0]);
}
console.log(arr);
Upvotes: 1
Reputation: 386560
You could group by first uppercase character with the character and all following items in a flat array.
const
data = ['Ajith', 'Arya', 'Akalya', 'Akila', 'Bharath', 'Bhakya', 'Kavitha', 'Kamal', 'Bavi'],
result = Object
.values(data.reduce((r, s) => {
const key = s[0].toUpperCase();
(r[key] ??= [key]).push(s);
return r;
}, {}))
.sort(([a], [b]) => a.localeCompare(b))
.flat();
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 2
Reputation: 192
let names = ['Ajith', 'Arya', 'Akalya', 'Akila', 'Bharath', 'Bhakya', 'Kavitha', 'Kamal', 'Bavi'];
let result = [];
let firstLetters = new Set();
for (let i = 0; i < names.length; i++) {
firstLetters.add(names[i][0]);
}
firstLetters = Array.from(firstLetters).sort();
for (let i = 0; i < firstLetters.length; i++) {
result.push(firstLetters[i]);
for (let j = 0; j < names.length; j++) {
if (names[j][0] === firstLetters[i]) {
result.push(names[j]);
}
}
}
console.log(result);
Upvotes: 0
Reputation: 177786
Something like this? Seems simpler than what was posted so far
const arr = ['Ajith', 'Arya', 'Akalya', 'Akila', 'Bharath', 'Bhakya', 'Kavitha', 'Kamal', 'Bavi']
const newArr = arr
.slice() // copy
.sort();
let letter = "";
for (let i=0; i<newArr.length; i++) {
const thisLetter = newArr[i].charAt(0);
if (thisLetter !== letter) {
letter = thisLetter;
newArr.splice(i,0,thisLetter)
}
}
console.log(newArr)
Upvotes: 1
Reputation: 3993
You can use map
let names = ['Ajith', 'Arya', 'Akalya', 'Akila', 'Bharath', 'Bhakya', 'Kavitha', 'Kamal', 'Bavi'];
let map = new Map();
names.forEach(item => {
let firstLetter = item[0].toUpperCase();
if (!map.has(firstLetter)) {
map.set(firstLetter, [firstLetter]);
}
map.get(firstLetter).push(item);
});
let result = [];
map.forEach(value => {
result.push(...value);
});
console.log(result);
You can also make every letter a separate group
let name = ['Ajith', 'arya', 'Akalya', 'Akila', 'Bharath', 'Bhakya', 'Kavitha', 'Kamal', 'Bavi'];
let map = new Map();
name.forEach(item => {
let firstLetter = item[0].toUpperCase();
if (!map.has(firstLetter)) {
map.set(firstLetter, [firstLetter]);
}
map.get(firstLetter).push(item);
});
let result = [];
map.forEach(value => {
result.push(value);
});
console.log(result);
Upvotes: 0
Reputation: 46
Here's a solution, probably not the most optimized one, but it should work :
The idea is to sort the array, loop over all the elements to compare the first letter in order to create a subgroup title.
It would look something like this :
var displaySortedArray = function(array) {
var sortedArray = array.sort();
console.log(sortedArray[0].charAt(0));
console.log(sortedArray[0]);
for(let index = 1 ; index < sortedArray.length ; index++){
if(sortedArray[index].charAt(0) != sortedArray[index-1].charAt(0)){
console.log(sortedArray[index].charAt(0));
}
console.log(sortedArray[index]);
}
}
displaySortedArray(['Test','SUUUU','Easy','Try2','Elements','Super','Amazing']);
Have a good day.
Upvotes: 2
Reputation: 10597
This is possible to do using a single reduce
call which I find quite elegant:
const data = ['Ajith', 'Arya', 'Akalya', 'Akila', 'Bharath', 'Bhakya', 'Kavitha', 'Kamal', 'Bavi'];
console.log(
data
.sort()
.reduce(
(items, item, index, array) => {
console.log({ prev: array[index - 1], current: item });
if (array[index - 1]?.[0] !== item[0]) {
items.push(item[0]);
}
items.push(item);
return items;
},
[]
)
);
Upvotes: 1
Reputation: 97130
Can reduce()
everything to an object, indexed by the first letter:
const data = ['Ajith', 'Arya', 'Akalya', 'Akila', 'Bharath', 'Bhakya',
'Kavitha', 'Kamal', 'Bavi'];
const result = [...data].sort().reduce((a, v) => {
const [first] = v;
a[first] ??= [];
a[first].push(v);
return a;
}, {});
console.log(result);
This object will have the keys in the correct order because sort()
was called first on (a copy of) the array, and string keys are maintained in insertion order.
If you want to convert that object to a flat array, you can just do:
const array = Object.keys(result).flatMap((k) => [k, ...result[k]]);
Upvotes: 2
Reputation: 12909
You can simply do as your title says — 'group-by' first letter, then map the result.
const input = ['Ajith', 'Arya', 'Akalya', 'Akila', 'Bharath', 'Bhakya', 'Kavitha', 'Kamal', 'Bavi',];
const grouped = {};
for (const word of input) {
(grouped[word[0].toUpperCase()] ??= []).push(word);
}
const result = Object.entries(grouped).flatMap(([k, vs]) => [k, ...vs]);
console.log(result);
Upvotes: 2