cyberkitty
cyberkitty

Reputation: 37

Creating key-value pairs with js reduce() and creating an array as the value

I am having a problem with javascript's reduce() function; I have to put arrays as the value. I can sucessfully create an array but can't add new values to it.

There's an array with words and I have to create a 'map' whose keys are the first letters of the words and the values are the words which start with the said letter.

arr = ["Here", "is", "a", "sentence", "with", "a", "lot", "of", "words"];

The expected output should be this:

{ ​h: [ "here" ],
  ​i: [ "is" ],
  ​a: [ "a", "a" ],
  ​s: [ "sentence", ]​,
  w: [ "with", "words" ]​,
  l: [ "lot" ],
  ​o: [ "of" ]
}

This is my solution to the problem but it overwrites existing values.

function my_func (param)
{
   return param.reduce ( (returnObj, arr) => {
    returnObj[arr.charAt(0)] = new Array(push(arr));
    return returnObj;
  } , {})

}

I tried this but it didn't work because it couldn't deduce the type for valueOf() and it yielded an error.


function my_func (param)
{
   return param.reduce ( (returnObj, arr) => {
    returnObj[arr.charAt(0)] = (new Array(returnObj[arr.charAt(0)].valueOf().push(arr)));
    return returnObj;
  } , {})

}

Upvotes: 1

Views: 3022

Answers (4)

adiga
adiga

Reputation: 35222

You are overwriting the accumulator object's property every time. Instead, check if an item with the character has already been added using the || operator and create a new array if it doesn't exist yet.

let array = ["Here", "is", "a", "sentence", "with", "a", "lot", "of", "words"]

function my_func(param) {
  return param.reduce((acc, str) => {
    let char = str.charAt(0).toLowerCase();
    acc[char] = acc[char] || [];
    acc[char].push(str.toLowerCase());
    return acc;
  }, {})
}

console.log(my_func(array))

Upvotes: 1

Uday Hiwarale
Uday Hiwarale

Reputation: 4157

var result = ["Here", "is", "a", "sentence", "with", "a", "lot", "of", "words"].reduce(function(map, value) {

  var groupKey = value.charAt(0).toLowerCase();
  var newValue = value.toLowerCase();

  return map[groupKey] = map.hasOwnProperty(groupKey) ? map[groupKey].concat(newValue) : [newValue], map;
}, {});

console.log( result );

Upvotes: 0

irek
irek

Reputation: 23

param.reduce((acc, el) => {
  const key = el[0] // use `el[0].toLowerCase()` for case-insensitive 
  if (acc.hasOwnProperty(key)) acc[key].push(el)
  else acc[key] = [el]
  return acc
}, {})

Upvotes: 0

lankovova
lankovova

Reputation: 1426

Check out my solution below. Hope this helps!

const arr = ["Here", "is", "a", "sentence", "with", "a", "lot", "of", "words"];

const getWordsDict = (array) => array.reduce(
  (acc, word) => {
    const lowerCasedWord = word.toLowerCase()
    const wordIndex = lowerCasedWord.charAt(0)

    return {
      ...acc,
      [wordIndex]: [
        ...(acc[wordIndex] || []),
        lowerCasedWord,
      ],
    }
  }, 
  {}
)

console.log( getWordsDict(arr) )

Upvotes: 0

Related Questions