Home > other >  Group by array with first letter in javascript
Group by array with first letter in javascript

Time:01-31

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

CodePudding user response:

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

CodePudding user response:

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

CodePudding user response:

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

CodePudding user response:

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;
      },
      []
    )
);

Codepen

CodePudding user response:

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']);
This function is an example and prints what you asked for, however i can't tell you how to implement this where you need it.

Have a good day.

CodePudding user response:

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

CodePudding user response:

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)

CodePudding user response:

Here is how you can do it :

const inputArray = ['Ajith', 'Arya', 'Akalya', 'Akila', 'Bharath', 'Bhakya', 'Kavitha', 'Kamal', 'Bavi'];
const resultArray = [];
const letters = new Set();

for (const item of inputArray) {
  const letter = item[0].toUpperCase();
  if (!letters.has(letter)) {
    letters.add(letter);
    resultArray.push(letter);
  }
  resultArray.push(item);
}

console.log(resultArray);

CodePudding user response:

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

CodePudding user response:

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

CodePudding user response:

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)

  • Related