【问题标题】:How to create an empty array only in first iteration of loop and then keep using it?如何仅在循环的第一次迭代中创建一个空数组然后继续使用它?
【发布时间】:2021-01-10 01:54:33
【问题描述】:

我是 javascript 新手。我有两个函数,一个叫做arrayToList,它接受一个数组并从中生成一个列表,另一个叫做listToArray,它接受一个列表并从中生成一个数组。第一个工作正常。但是,如果是第二个,我必须 仅在第一次迭代中创建一个空数组 for 或 while 循环,在该循环中,我会将列表的每个值传递给我创建的数组,并在每个步骤删除 list.value 并将列表设置为 list.rest(即列表的其余部分),然后递归地继续调用相同的函数。

我的问题是我无法在函数中声明数组。如果我说if(!array) {let array=[];},那么我会收到数组未定义的消息,如果我将数组声明为全局,那么它会在不同的函数调用中保留值,这是我不想要的。下面是代码。感谢您的帮助。

let array=[];


function listToArray(list) {
  
  while(list.value) {
    
    array.push(list.value);
    delete list.value;
    list=list.rest;
    listToArray(list);
    
   }
  
  return array;
 
  
}

console.log(listToArray({value: 10, rest: {value: 20, rest: {
value:  30
rest:   {value: 50, rest: {value: 70, …}}));

【问题讨论】:

    标签: javascript arrays list recursion


    【解决方案1】:

    我将使用默认为空数组的默认第二个参数,然后将其传递:

    function nestedObjToArray(obj, arr = []) {
      arr.push(obj.value);
      if (obj.rest) {
        nestedObjToArray(obj.rest, arr);
      }
      return arr;
    }
    
    console.log(nestedObjToArray({
      value: 10,
      rest: {
        value: 20,
        rest: {
          value: 30,
          rest: {
            value: 50,
            rest: {
              value: 70,
            }
          }
        }
      }
    }))

    这样,在第一次调用函数时会创建数组,因为函数最初不是使用第二个参数调用的。在随后的递归调用中,创建的数组作为第二个参数向下传递。

    请注意,“列表”在 JS 中并不是具有普遍理解的普遍含义的东西。有些人可能认为您指的是普通数组。由于您传递的是嵌套对象,因此您可以调用函数 nestedObjToArray 或类似的东西。

    如果不能传递其他参数,可以在最后的递归调用上创建数组并返回:

    function nestedObjToArray(obj) {
      const arr = obj.rest ? nestedObjToArray(obj.rest) : [];
      arr.unshift(obj.value);
      return arr;
    };
    
    console.log(nestedObjToArray({
      value: 10,
      rest: {
        value: 20,
        rest: {
          value: 30,
          rest: {
            value: 50,
            rest: {
              value: 70,
            }
          }
        }
      }
    }))

    【讨论】:

    • 嗨@CertainPerformance,谢谢你的回答。您的方法是实现预期效果的好方法,我也想到了类似您所写的内容,但我的问题是是否有一种方法可以在不传递第二个参数的情况下做到这一点?如果我们在方法调用中不传递第二个参数,那么它会自动创建数组吗?
    • 您可以在最后的递归调用中创建数组,但这样 IMO 会更加混乱
    • 好的,我忘记了如何使用默认参数。谢谢提醒,你的方法是要走的路。非常感谢。
    【解决方案2】:

    您可以采用递归方法而不使用数组来收集嵌套项。

    function nestedObjToArray({ value, rest }) {
        return [value, ...(rest ? nestedObjToArray(rest) : [])];
    }
    
    console.log(nestedObjToArray({ value: 10, rest: { value: 20, rest: { value: 30, rest: { value: 50, rest: { value: 70 } } } } }));

    【讨论】:

    • 嗨尼娜,谢谢你的回答。它可以工作,但我不想最好传递第二个参数,我是菜鸟,所以你的代码对我来说似乎有点难以理解。无论如何,感谢您的帮助,@CertainPerformance 为您的方法提供了更容易理解的替代方法。当我不再是菜鸟时,我会使用你的方法:),现在它吓到我了。
    • @sb16:那里只有一个参数。它被简单地解构以允许直接访问其属性。这相当于const listToArray = (x) => [x.value, ...(x.rest ? listToArray(x.rest) : [])]
    猜你喜欢
    • 2023-03-19
    • 1970-01-01
    • 2020-08-24
    • 2010-12-23
    • 1970-01-01
    • 2017-11-16
    • 1970-01-01
    • 2017-08-19
    相关资源
    最近更新 更多