循环由于某种原因被卡住,然后最终返回未定义

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了循环由于某种原因被卡住,然后最终返回未定义相关的知识,希望对你有一定的参考价值。

这是我要解决的问题:给定:包含名称哈希的数组

返回:一个字符串,其格式为以逗号分隔的名称列表,但最后两个名称除外,该两个名称之间应使用与号分隔。

示例:

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

注意:所有散列都经过预先验证,并且仅包含A-Z,a-z,'-'和'。

这是我的代码:

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>

您能帮我解决吗?另外,如果您无法回答,请不要拒绝我的问题。在我得到答案之前,它消除了问题。预先谢谢你

答案

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

var finalNames = names.map(returnNames);
另一答案

正如他们已经指出的,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'])
另一答案

我已经使用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))
另一答案

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

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']);
另一答案

您的代码有两个问题。如果您检查您的代码

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

forEach中,您正在传递returnNames作为回调。 forEach将遍历数组的每个元素。将每个元素传递给提供的回调并执行它。

如您所见,在回调内部,您再次使用for循环遍历整个列表。如此有效,对于每个元素,您都在遍历整个列表,从而将复杂度提高到O(n2)

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

  finalNames.length / i == 1

length属性无法读取。

另一答案
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”]

以上是关于循环由于某种原因被卡住,然后最终返回未定义的主要内容,如果未能解决你的问题,请参考以下文章

pod卡住导致物理机挂了

手机刷机卡住怎么办

如何循环消息

SQL服务器卡住了

Vtiger 7.1 安装卡住了

在 notifyDataSetChanged 上未调用 GetView,ListView 卡住