1

这是我要解决的问题:Given: an array contains hashes of names

返回: 格式为以逗号分隔的名称列表的字符串,最后两个名称除外,最后两个名称应由 & 号分隔。

例子:

list([ {name: 'Bart'}, {name: 'Lisa'}, {name: 'Maggie'} ])
// returns 'Bart, Lisa & Maggie'

list([ {name: 'Bart'}, {name: 'Lisa'} ])
// returns 'Bart & Lisa'

list([ {name: 'Bart'} ])
// returns 'Bart'

list([])
// returns ''

注意:所有哈希都经过预先验证,并且仅包含 AZ、az、'-' 和 '。

这是我的代码:

var finalName;
var notFinal;

function list(names){
  var finalNames = names.forEach(returnNames);
        console.log(typeof finalNames);

  function returnNames() {
    for (var i = 0; i<names.length; i++) {
      var nameValue = Object.keys(names[i]).map(key => names[i][key])
    }
  }

  for(var i = 0; i<finalNames.length; i++) {
    if (finalNames.length / i == 1) {
      finalName = "& " + finalNames[i]; 
    }
    else {
      notFinal = finalNames[i] + ", ";
    }
  }

  console.log(notFinal + finalName);
}

list([{name: 'Bart'},{name: 'Lisa'},{name: 'Maggie'},{name: 'Homer'},{name: 'Marge'}])

它卡在循环中,最后报错:

TypeError: Cannot read property 'length' of undefined
    at list
    at /home/codewarrior/index.js:30:1
    at Object.handleError
        <anonymous>

我如何解决它?

4

6 回答 6

3

那是因为 forEach 不返回任何内容,请尝试使用 map 函数。

var finalNames = names.map(returnNames);
于 2020-06-07T06:06:39.543 回答
2

正如他们已经指出的那样,Array.prototype.forEach返回undefined。相反,您可以使用.map它,修改您的returnNames功能

var finalName;
var notFinal;

function list(names){
  // Changed .forEach with .map
  var finalNames = names.map(returnNames);
  console.log(typeof finalNames);

  function returnNames(person) {
    // If you only need to get the object values, use Object.values instead of Object.keys
    return Object.values(person);
  }

  for(var i = 0; i < finalNames.length; i++) {
    // Added + 1 because i could never be equal to the array length
    // Note that you'll need to make 1 or 2 more changes before this code works as expected
    if (finalNames.length / (i + 1) == 1) {
      finalName = "& " + finalNames[i]; 
    }
    else {
      notFinal = finalNames[i] + ", ";
    }
  }

  console.log(notFinal + finalName);
}

list([{name: 'Bart'},{name: 'Lisa'},{name: 'Maggie'},{name: 'Homer'},{name: 'Marge'}])

于 2020-06-07T06:15:45.330 回答
1

您可以像下面这样简化您的代码。

function list(names){
  //Determine length of array (= number of names)
  const len = names.length;
  //Use a simple for loop to go through the array
  let newNames = "";
  for (i=0; i<len; i++) {
    newNames += names[i].name;
    if ( i<len-2 ) newNames += ", "
      else if ( i<len-1 ) newNames += " & "
  }
  console.log(newNames);
}

list([{name: 'Bart'},{name: 'Lisa'},{name: 'Maggie'},{name: 'Homer'},{name: 'Marge'}])
list([{name: 'Bart'}, {name: 'Lisa'}]);
list([{name: 'Bart'}]);

于 2020-06-07T06:22:01.523 回答
1

我已经用来reduce查找最终字符串以根据您的要求显示名称。希望这可以帮助。

formatString = (list) => {
    let length = (list || []).length;
    return list.reduce((result, obj, index) => {
        result += obj.name || "";
        if(index + 1 === length - 1) {
            result += " & ";
        } else if(index !== length - 1) {
            result += ", ";
        }
return result;
    }, "")
}

let list = [{"name":"Bart"},{"name":"Lisa"},{"name":"Maggie"},{"name":"Homer"},{"name":"Marge"}]
console.log(formatString(list))

list = [ {name: 'Bart'}, {name: 'Lisa'} ]
console.log(formatString(list))

list = [ {name: 'Bart'} ]
console.log(formatString(list))

list = []
console.log(formatString(list))

于 2020-06-07T06:22:24.210 回答
1

您的代码有两个问题。如果你通过你的代码

function list(names){
  var finalNames = names.forEach(returnNames);
    console.log(typeof finalNames);

  function returnNames() {
    for (var i = 0; i<names.length; i++) {
    var nameValue = Object.keys(names[i]).map(key => names[i][key])
   }
 }

forEachreturnNames作为回调传递。AforEach将遍历数组的每个元素。将每个元素传递给提供的回调并执行它。

如您所见,在您的回调中,您再次使用 for 循环遍历整个列表。如此有效地,对于每个元素,您将再次遍历整个列表,从而增加复杂性O(n2)

第二个问题,正如其他答案所指出的那样,您没有从forEach回调中返回任何内容。因此, 的值finalNames变为undefined。所以,当你运行这个语句

  finalNames.length / i == 1

length无法读取属性。

于 2020-06-07T06:28:18.257 回答
1
function returnNameListString(namelist){
    if (namelist.length){
        return
    }else if(namelist.length===1){
        return toString(namelist)
    }else{
        nameString = namelist[0]
        for(var i=1; i<(namelist.length-1);i++){
            nameString = nameString + ", " + namelist[i]
        }
        nameString = nameString + " & " + namelist[namelist.length-1]
        return nameString
    }

}

尝试这个!将名称声明为列表 ["tom", "dick", "harry"]

于 2020-06-07T06:41:01.083 回答