1

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

}
1
  • I understand your question, but if you are using lodash library, you can use groupBy function like : _.groupBy( ["Here", "is", "a", "sentence", "with", "a", "lot", "of", "words"], v => v.charAt(0).toLowerCase() ); Commented Mar 31, 2019 at 12:54

4 Answers 4

1

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

Sign up to request clarification or add additional context in comments.

1 Comment

You forgot to lower case the word itself, before pushing it.
0

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

Comments

0
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
}, {})

Comments

0

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

1 Comment

You forgot to lower case the word itself, before pushing it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.