开发者问题收集

按第一个字符对输入数组的每个元素进行分组并返回为对象

2021-04-27
174

我有以下任务

Given an array of strings, write a function that returns an object that groups each of the input array's elements by the first character.

我的代码如下。我收到一个错误((用注释突出显示)说

TypeError: Cannot read property '0' of undefined

有人能向我解释一下为什么它说它未定义吗?

function groupBy(arr) { 
  var result = {};
  var container = []
  
  for (var i = 0; i < arr.length; i++) {
    var currentWord = arr[i];
    var firstChar = currentWord[0];
    var nextWord = arr[i + 1];
    var secondChar = nextWord[0]; // Error here

    if (firstChar === secondChar) {
      container.push(currentWord, nextWord)
    } else {
      container.push(currentWord)
    }

    result[firstChar] = container;
  }
  return result;
}
console.log(groupBy(['apple', 'cat', 'boat', 'card', 'bond']));

// returns { 'a': ['apple'], 'c': ['cat', 'card'], 'b': ['boat', 'bond'] }
3个回答

基本上可以用一行代码完成:

function groupBy(arr){return arr.reduce((a,c)=>((a[c[0]]=a[c[0]]||[]).push(c),a), {}) };
console.log(groupBy(['apple', 'cat', 'boat', 'card', 'bond']));

工作通过以下表达式完成:

arr.reduce((a,c)=>((a[c[0]]=a[c[0]]||[]).push(c),a), {})

在此 .reduce() 调用中,我使用从每个数组元素 c[0] 的第一个字母中获取的键组装一个对象。我通过应用 || 运算符来检查具有此键的属性是否已存在:

=a[c[0]]||[]

如果键已存在( a[c[0]] 为“truthy”),则将返回已建立的数组,否则将创建一个新数组( [] )并存储在此属性下。然后使用 .push(c)c (当前数组元素)推送到此 a[c[0]] 数组上。之后是逗号和 a :累积对象作为 reduce() 回调函数的结果返回。

Carsten Massmann
2021-04-27

您的代码在

var nextWord = arr[i + 1];
处中断

将 for 循环设置为 arr.length-1

for (var i = 0; i < arr.length - 1; i++)
MidKar
2021-04-27

仅查看代码,这可能是由于当它到达最后一个单词“bond”时,因为在它表示未定义之后没有任何内容。您可能希望使用类似“如果 arr[i + 1] 为真则设置变量”之类的方法缓解这种情况。

Justin
2021-04-27