Yoël Zerbib
Yoël Zerbib

Reputation: 187

Get filtered array (values with the same first letter) from this array

I need to create a function indexWords() that takes an array as parameter and return an object with the first letter of the words as key and each keys list all of the words that start with this letter.

Here an exemple because my english is really bad lol:

indexWords(["apple", "car", "cat"]) // output:  {a: ["apple"], c: ["car", "cat"]}

so I started to get an array with the first letter and remove duplicates letter by doing like so:

indexWords(arr) {    
let firstLetters = [... new Set(arr.map(x => x[0]))]

}

But then I need to filter the given arr and create a new mapped array for each values that have the same first letter. Basically I should check if arr[i][0] === firstLetters[0], and then firstLetters[1] etc. But how to know how many index will be into firstLetters ? I'm lost...

Upvotes: 2

Views: 754

Answers (4)

Sifat Haque
Sifat Haque

Reputation: 6067

You can use Array.reduce() method to solve this problem. Please check my solution. (It also solves the duplicate issue)

  function indexWords(arr) {
    return arr.reduce((obj, item) => {
      const firstChar = item[0];
      if (!obj[firstChar]) obj[firstChar] = [item];
      else obj[firstChar] = [...new Set([...obj[firstChar], item])];
      return obj;
    }, {});
  }
  console.log(indexWords(["apple", "car", "cat", "cat"]));

Upvotes: 4

Arjun Biju
Arjun Biju

Reputation: 73

let res = _.groupBy(["apple", "car", "cat"], (val)=>(val[0]))
console.log("result",res)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js"></script>

you can also use https://lodash.com/docs/4.17.15#groupBy to achieve this

Upvotes: 0

Jorjon
Jorjon

Reputation: 5434

What you want is not a Set but a Map.

const indexWords = array => array.reduce((map, curr) => map.set(curr[0], ( map.get(curr[0]) || new Array()).concat(curr) ), new Map());

const output = indexWords(["apple", "car", "cat"]);
console.log(Object.fromEntries(output));

// output:  {a: ["apple"], c: ["car", "cat"]}

Commented:

const indexWords = array =>
  array.reduce((map, curr) =>
    map.set(curr[0], // curr[0] represents the first character. We are going to change the value corresponding to the first character.
    (
      map.get(curr[0]) || new Array()) // initialization (kind of getOrDefault in Java)
      .concat(curr)  // appends the value to the corresponding array
    ), new Map() // we start fresh with a new Map
);

Upvotes: 2

Derek Wang
Derek Wang

Reputation: 10204

You can use Array.reduce to build the array as follows.

function indexWords(input) {
  return input.reduce((acc, cur) => {
    acc[cur[0]] ? acc[cur[0]].push(cur) : acc[cur[0]] = [ cur ];
    return acc;
  }, {});
}

console.log(indexWords(["apple", "car", "cat"]));

Upvotes: 5

Related Questions