首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >数组以未定义的形式给出最后一个元素。

数组以未定义的形式给出最后一个元素。
EN

Stack Overflow用户
提问于 2020-07-19 15:15:12
回答 3查看 714关注 0票数 0

我正在尝试编写一个函数,该函数从数组中删除项,您可以通过undo函数撤消删除。如果您将一个参数传递给undo函数,以0作为第一项,然后传递2(作为3项),则返回最后一项未定义的参数,我不知道为什么会发生这种情况。我试着调整撤销函数,有时它会返回数组中的空位置,甚至是空的x2。

有人能解释一下为什么会发生这种事吗?

代码语言:javascript
复制
let testLista = ['Mars', 'Jupiter', 'Saturn', 'Sun'];
let testUndo = [];
let i = 0;

const delItem = del => {
    let indexOfDel = testLista.indexOf(del);
    if(testLista.includes(del)){
        testLista.splice(indexOfDel, 1);
        document.write(`<h3>Deleted: <em>${del}</em></h3>`)
        testUndo[i] = del;
        console.log('delItem() undo - ',testUndo);
        console.log('delItem() list - ',testLista);
        i++;
    }else{
       document.write(`<h2>That item does not exist! Available items: <em>${testLista.join(', ')}</em></h2>`);
    }
}

delItem('Sun');
delItem('Saturn');
delItem('Mars');
 
const undoFunc = (undo) => {

    if(undo >= 1 && undo < testUndo.length){
        for(let j = 0; j <= undo; j++){
            testLista[testLista.length] = testUndo[j];
            testUndo.splice(j, 1);
            console.log('Undo() - ', testUndo);
        }
    }else{
        testLista[testLista.length] = testUndo[testUndo.length-1];
        console.log('Undo() - ', testLista)
    }

};

这是我的html:

代码语言:javascript
复制
    <html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    
    <script src="main.js"></script>
</body>
</html>
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-07-19 15:56:03

这个问题是由于您的testUndo.splice(j, 1);函数中的undo

splice()方法在给定索引处将项添加/移除到数组中,并返回删除的项。

Note__:此方法更改原始数组。

您正在迭代j和向上的j<2

代码语言:javascript
复制
for j=0 | testUndo = ["Sun", "Saturn", "Mars"]

spice将删除索引 i.e testUndo = ["Saturn", "Mars"]中的项。

代码语言:javascript
复制
`for j=1 | testUndo = ["Saturn", "Mars"]`

spice将删除索引1 i.e testUndo = ["Saturn"]中的项

for j=2 | testUndo = ["Saturn"]现在在索引2处没有项目,因此它不会删除任何东西。

解决方案-您应该在索引0的数组中拼接。

代码语言:javascript
复制
for(let j = 0; j <= undo; j++){
            testLista[testLista.length] = testUndo[0];
            testUndo.splice(0, 1);
            console.log('Undo() - ', testUndo);
        }
票数 0
EN

Stack Overflow用户

发布于 2020-07-19 16:11:34

在循环中使用splice通常会导致不希望得到的结果:当您通过它缩小数组的大小,但增加循环变量时,您会遇到两个问题:

  1. --您将跳过元素:splice向左移动值,以填补已删除值的空白。但是在下一次迭代中仍然会增加j,因此有一个值从迷宫中滑过.

当数组变得越来越短时,

  1. 最终会指向一个索引,如果没有缩短数组,那么这个索引就会存在,但是现在它更短了,它指向数组末尾以外的位置,从而得到undefined值。

解决方案是不在循环中使用splice,而只在循环之后使用一次,在循环之后,它可以一次删除所有迭代值:

代码语言:javascript
复制
        for(let j = 0; j <= undo; j++){
            testLista[testLista.length] = testUndo[j];
            console.log('Undo() - ', testUndo);
        }
        testUndo.splice(0, undo+1);

我应该注意,将undo定义为要删除的最后一个索引有点不合常规。将undo定义为要删除的项的计数将更有意义。

另外,为什么不使用testLista.push呢?

那你就会:

代码语言:javascript
复制
        for(let j = 0; j < undo; j++) { // now `undo` is a count!
            testLista.push(testUndo[j]);
            console.log('Undo() - ', testUndo);
        }
        testUndo.splice(0, undo); // no more `+1`

使用spread语法,您甚至可以去掉循环(仍然使用更符合逻辑的undo定义):

代码语言:javascript
复制
        testLista.push(...testUndo.splice(0, undo));
票数 1
EN

Stack Overflow用户

发布于 2020-07-19 16:12:58

另一个例子是:

代码语言:javascript
复制
let planets = ['Mercury', 'Venus', 'Earth', 'Mars', 'Jupiter', 'Saturn', 'Sun'];
let deletedPlanets = [];
const planetList = document.getElementById('planet-list');
const deletePlanet = (planet) => {
  const ind = planets.indexOf(planet);
  deletedPlanets.push({ind, planet});
  planets.splice(ind, 1);
  drawPlanetList();
};
const drawPlanetList = () => {
    planetList.innerHTML = '';
    planets.forEach((planet) => {
    const div = document.createElement('div');
    div.innerText = planet;
    div.onclick = () => {
        deletePlanet(planet);
    };
    planetList.appendChild(div);
  });
}
const deleteMultiple = () => {
    deletePlanet('Mars');
  deletePlanet('Jupiter');
  deletePlanet('Sun');
  
    drawPlanetList();
}
const undo = () => {
    if (!deletedPlanets.length) {
    return ;
  }
  const undoObj = deletedPlanets.pop();
  planets.splice(undoObj.ind, 0, undoObj.planet);
    drawPlanetList();
}
drawPlanetList();
代码语言:javascript
复制
div {
  padding: 0.4em;
  border-bottom: 1px inset gray;
}
代码语言:javascript
复制
Clicking on list elements deletes them.
<button onclick="deleteMultiple()">
 delete multiple
</button>
<button onclick="undo()">
 undo
</button>
<section id="planet-list"></section>

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62982094

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档