React / Javascript for循环 - 超出数组长度时从idx 0开始

Posted

技术标签:

【中文标题】React / Javascript for循环 - 超出数组长度时从idx 0开始【英文标题】:React / Javascript for loop - Start from idx 0 when exceeding array length 【发布时间】:2020-07-14 01:16:01 【问题描述】:

我希望你们中的一个能够帮助我解决 javascript / react 问题。 我正在构建一个 Web 应用程序,您作为用户可以在其中创建带有歌词 id 的设置列表。这意味着当打开一个 setlist 时,您可以查看该 setlist 中引用的每一个歌词。在窗口底部,我有一个上一个和下一个按钮,可让您查看列表中的下一个或上一个歌词。

我的问题是,当到达歌词列表的末尾/最后一个索引号并且我尝试单击下一步时,for 循环中断并且我的页面崩溃了。我想要它做的是,当达到歌词数组的长度并且您尝试超过时,for 循环再次从索引 0 重新启动。我尝试了多种事情和理论,但我似乎找不到任何有效的方法。

这是我拥有的歌词 ID 数组。

['Id1', 'Id2', 'Id3', 'Id4']

这是我检查当前索引号/当前正在查看的歌词 ID 的函数。该函数返回当前的索引号。

function checkLyricIdx() 
        let setlistLength = setlist.lyrics.length;
        for (var i = 0; i < setlistLength; i++) 
            if (setlist.lyrics[i] === chosenLyricId) 
                return i;
            
        
 

这里是“查看下一个歌词”功能,它首先检查当前索引号,然后使用下一个歌词 id 更新状态(通过增加 idx 号来实现)。

async function viewNextLyric(e) 
        e.preventDefault();
        let currentIndex = await checkLyricIdx();
        setChosenLyricId(setlist.lyrics[currentIndex + 1]);
    

查看前一个歌词id的功能和上面差不多,i只是对currentIndex减1。

只是为了澄清我的问题。我怎样才能重做这个函数,使它在超过数组长度时不会中断?我想要它,这样当试图超过数组的长度时,它会重新启动到索引 0 / 你再次查看列表。当我到达最后一个歌词 ID 并尝试单击下一步时,应用程序崩溃并显示以下内容:

TypeError: undefined is not an object (evalating 'chosenLyricId.length')

【问题讨论】:

【参考方案1】:

如果您希望索引从任一端换行,请使用模运算。

const dataArray = ['id1', 'id2', 'id3', 'id4', 'id5', 'id6', 'id7'];

const wrapIndex = (arr, index) => index % arr.length;

for (let i = 0; i < 50; i++) 
  console.log('Iteration', i, 'index', wrapIndex(dataArray, i), dataArray[wrapIndex(dataArray, i)]);

如果你愿意,你也可以绑定它。

const dataArray = ['id1', 'id2', 'id3', 'id4', 'id5', 'id6', 'id7'];

const bound = (min, max, val) => Math.max(min, Math.min(val, max));

const boundIndex = (arr, index) => bound(0, arr.length - 1, index);

for (i = -3; i < 10; i++) 
  console.log('Iteration', i, 'index', boundIndex(dataArray, i), dataArray[boundIndex(dataArray, i)]);

【讨论】:

【参考方案2】:

你可以像这样修改viewNextLyric函数

async function viewNextLyric(e) 
    e.preventDefault();
    let currentIndex = await checkLyricIdx();
    setChosenLyricId(setlist.lyrics[(currentIndex + 1) % setlist.lyrics.length]  );

因此,当您位于最后一个索引并单击下一步时,它会增加索引并执行取模运算,结果为 0。

你的viewPreviousLyric函数也需要修改

async function viewPreviousLyric(e) 
    e.preventDefault();
    let currentIndex = await checkLyricIdx();
    setChosenLyricId( currentIndex === 0? setlist.lyrics[setlist.lyrics.length-1] : setlist.lyrics[currentIndex - 1]  );

async function viewPreviousLyric(e) 
    e.preventDefault();
    let currentIndex = await checkLyricIdx();
    setChosenLyricId( currentIndex === 0? setlist.lyrics[0] : setlist.lyrics[currentIndex - 1]  );

取决于您希望以前的功能如何工作。

【讨论】:

谢谢,这个答案的工作方式与预期的完全一样。对于 viewPreviousLyric 函数,我采用了您建议的第一个函数。 :-) 现在,当到达末尾并单击下一步时,我再次从数组的开头开始,如果我从索引 0 / 第一项开始并单击上一个,那么它将转到数组中的最后一个 id。跨度>

以上是关于React / Javascript for循环 - 超出数组长度时从idx 0开始的主要内容,如果未能解决你的问题,请参考以下文章

React / Javascript for循环 - 超出数组长度时从idx 0开始

React 道具不适用于 for 循环

如何在react.js 中利用for循环之类的输出html

如何在react.js 中利用for循环之类的输出html

[react] 写例子说明React如何在JSX中实现for循环

react中的for循环