【问题标题】:How can I save the 'previous' and 'next' iteration of an object in a loop?如何在循环中保存对象的“上一个”和“下一个”迭代?
【发布时间】:2019-08-21 07:37:30
【问题描述】:

我正在开发一个程序,该程序在字符串出现之前和之后获取一个数字,然后比较这些数字 - 但只有当该字符串出现时才会发生。

我尝试过遍历 object.keys(也许我不明白如何正确)

我尝试过嵌套循环(在字符串“restart”中记录单个字母)

let formattedTemps = [ 10,'restart',68,80,'restart',70.1,'restart',
  72,80,'restart',69,'restart',78,'restart',84,100,300,50,'restart',70,
'restart',90,'restart',50,'restart',100 ]

const switch = (Array) => {
  console.log(formattedTemps)
  let previousValue = 0
  let nextValue = 0
  for (let elements of array) {
    console.log(previousValue)
    console.log(nextValue)
    // let previousValue = elements[-1]
    // let nextValue = elements[1]
    //console.log(previousValue , element, nextValue
        // save the iterables beside 'restart' on both sides here
      }
    }

我的预期结果是我在记录字符串“restart”之前和之后都得到了值(因为我会比较它们)。

发生的是一大堆未定义的值,即:多行未定义、“重新启动”、未定义(带有注释掉的代码)和多个 0,就像现在一样。

【问题讨论】:

  • temperature[-1] 未定义,您正在访问超出数组范围
  • 你说的是“循环中的循环”,但我只看到一层循环...?
  • 啊@T.J.Crowder 我之前在一个循环中尝试了一个循环,但是控制台。将重启记录为带有字符串值的单个字母

标签: javascript node.js loops iteration


【解决方案1】:

我们可以使用Array.reduce捕获累加器中迭代的最后一个索引(累加器或acc在我的代码中是Array.reduce回调的第一个参数)并且只打印previous和@987654326 @当当前元素为restart或任意string

这是我试图解释这背后的逻辑:

  • 在第一次迭代中,没有打印任何内容,因为元素是 number。我们只是将当前索引作为累加器的值返回。
  • 在第二次迭代中,条件typeof ele === "string" 得到满足,所以现在acc 的值是0(因为它保存了最后一次访问的索引),即previous,下一个比当前索引。
  • 每次数组迭代的最后一次访问索引都作为累加器的值 (acc) 返回,我们可以在当前迭代中使用它来查找前一个元素的值。然后我们打印当前元素是否为字符串。下一个元素的值将比数组的当前索引idx 多一个。

let formattedTemps = [ 10,'restart',68,80,'restart',70.1,'restart',
  72,80,'restart',69,'restart',78,'restart',84,100,300,50,'restart',70,
'restart',90,'restart',50,'restart',100 ]

const highLimitSwitch = (formattedTemps) => {
  formattedTemps.reduce((acc, ele, idx, arr) => {
   if(typeof arr[acc] === "number" && typeof ele === "string" && typeof arr[idx + 1] === "number"){
     console.log(`${arr[acc]} ${ele} ${arr[idx + 1]}`)
   }
   return idx;
  }, 0)
}
highLimitSwitch(formattedTemps);

【讨论】:

  • 这是一种奇怪的reduce使用方式
  • @JordanS 感觉像是 hack 吗? :)
  • 感觉像个黑客。 Reduce 已经有点不确定了,但这很疯狂:)
  • 感谢您的解释,我对 .map()、.reduce() 和 .filter() 做了一些研究,但我仍然觉得自己掌握了窍门 - 一直在编码和关闭了 2 年,但这是第一次它没有成为一些教程或其他东西的一部分。
  • @JasonHarder - 这戏剧性地比它需要的更复杂,并且没有做任何事情来确保restart 两侧的操作数是数字。您所需要的(正如我所演示的)只是一个简单的循环。
【解决方案2】:

使用索引而不是for of 循环。然后,如果该索引处的元素是'restart',则可以返回一个索引并转发一个索引来获取值。

let formattedTemps = [ 10,'restart',68,80,'restart',70.1,'restart',
  72,80,'restart',69,'restart',78,'restart',84,100,300,50,'restart',70,
'restart',90,'restart',50,'restart',100 ]

for (let i = 0; i < formattedTemps.length; i++) {
  let temp = formattedTemps[i]
  if (typeof temp === 'string') {
    beforeTemp = formattedTemps[i-1];
    afterTemp = formattedTemps[i+1];
    console.log(beforeTemp, temp, afterTemp);
  }
}

【讨论】:

  • 您可以为第一个和最后一个索引配对添加检查。
  • 这假定数据格式正确,但你是对的。
【解决方案3】:

如果实际值是字符串,您可以映射新数组。然后过滤并保留数组。

var array = [10, 'restart', 68, 80, 'restart', 70.1, 'restart', 72, 80, 'restart', 69, 'restart', 78, 'restart', 84, 100, 300, 50, 'restart', 70, 'restart', 90, 'restart', 50, 'restart', 100],
    result = array
        .map((v, i, a) => typeof v === 'string' && [a[i - 1], v, a[i + 1]])
        .filter(Boolean);

console.log(result.map(a => a.join(' ')));
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

    【解决方案4】:

    您可以访问数组的任意一侧,这将为您提供值undefined。因此,您可以检查字符串的任一侧是否有数字:

    const highLimitSwitch = (formattedTemps) => {
      for (const [index, operation] of formattedTemps.entries()) {
          const num1 = formattedTemps[index - 1];
          const num2 = formattedTemps[index + 1];
          if (typeof num1 === "number" && typeof operation === "string" && typeof num2 === "number") {
              console.log(num1, operation, num2);
          }
      }
    };
    

    实时示例:

    let formattedTemps = [10,'restart',68,80,'restart',70.1,'restart',
      72,80,'restart',69,'restart',78,'restart',84,100,300,50,'restart',70,
    'restart',90,'restart',50,'restart',100 ];
    
    const highLimitSwitch = (formattedTemps) => {
      for (const [index, operation] of formattedTemps.entries()) {
          const num1 = formattedTemps[index - 1];
          const num2 = formattedTemps[index + 1];
          if (typeof num1 === "number" && typeof operation === "string" && typeof num2 === "number") {
              console.log(num1, operation, num2);
          }
      }
    };
    
    highLimitSwitch(formattedTemps);
    .as-console-wrapper {
      max-height: 100% !important;
    }

    (注意70.1 被使用了两次,分别作为num2 和下一次操作的num1,因为样本数据中两个'restart's 之间只有一个数字。)


    或者如果你可以假设当你看到一个字符串时它的两边都有数字(就像你的currently-accepted answer一样),那么它就更简单了:

    const highLimitSwitch = (formattedTemps) => {
      for (const [index, operation] of formattedTemps.entries()) {
          if (typeof operation === "string") {
              const num1 = formattedTemps[index - 1];
              const num2 = formattedTemps[index + 1];
              console.log(num1, operation, num2);
          }
      }
    };
    

    实时示例:

    let formattedTemps = [10,'restart',68,80,'restart',70.1,'restart',
      72,80,'restart',69,'restart',78,'restart',84,100,300,50,'restart',70,
    'restart',90,'restart',50,'restart',100 ];
    
    const highLimitSwitch = (formattedTemps) => {
      for (const [index, operation] of formattedTemps.entries()) {
          if (typeof operation === "string") {
              const num1 = formattedTemps[index - 1];
              const num2 = formattedTemps[index + 1];
              console.log(num1, operation, num2);
          }
      }
    };
    
    highLimitSwitch(formattedTemps);
    .as-console-wrapper {
      max-height: 100% !important;
    }

    【讨论】:

    • 没关系 - 就我的目的而言,可以多次比较相同的数字。现在让我学习和学习实施! (谢谢!)
    • const highLimitSwitch = (formattedTemps) =&gt; { for (const [index, operation] of formattedTemps.entries()) { //因为 .enteries 可以分解为键值对 - 我们告诉 javascript 第一个是索引,第二个是定义的数据类型 ** const num1 = formattedTemps[index - 1]; const num2 = formattedTemps[index + 1]; * *方括号让javascript知道num1和2是迭代
    • if (typeof num1 === "number" &amp;&amp; typeof operation === "string" &amp;&amp; typeof num2 === "number") { console.log(num1, operation, num2); } } }; typeOf 参数必须是字符串。
    • @JasonHarder - 不,typeof 操作数不需要是字符串。如果是这样的话,typeof 就没有意义了。在你的控制台中试试这个:const a = 42; console.log(typeof a);typeofresult 总是一个字符串,但它的操作数可以是任何东西。答案中的检查是正确的。
    • 好吧,我的意思是说,如果您要查找数字,typeOf 参数将是“数字”,它是一个字符串 - 所以我要么误解了,要么沟通不畅
    猜你喜欢
    • 2015-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-29
    • 2020-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多