【问题标题】:Can't access any arrays after sorting another array排序另一个数组后无法访问任何数组
【发布时间】:2016-04-12 06:44:32
【问题描述】:

我遇到了一个很奇怪的bug: 我从另一个数组(tours[])派生了一个新数组allSavings[],并在函数calculateAllSavings() 中对其进行排序。在调用该函数之前,我可以访问 tours[] 就好了,但之后,我就不能了。 div 标签demo1demo2 都存在并且对于其他输出都可以正常工作。

function euclDist(node1,node2){
    if(node1 != node2){
        var x = Math.pow(nodes[node2].x - nodes[node1].x,2);
        var y = Math.pow(nodes[node2].y - nodes[node1].y,2);
        var dist = Math.sqrt(x+y);
        return dist;
    }
    else return 0.0;
}

function tourDist(members){
    var tourDist = 0.0;
    if (members.length>1){
            for (i = 1; i < members.length; i++)
                tourDist += euclDist(members[i],members[i-1]);
    }
    return tourDist;
}

function combineTours(tourA, tourB){
    tourA.pop();
    tourB.shift();
    return tourA.concat(tourB);
}

function calculateSaving(tourA,tourB){
    var costSeparate = tourDist(tourA) + tourDist(tourB);
    var combTour = combineTours(tourA,tourB);
    var costCombined = tourDist(combTour);
    return costSeparate - costCombined;
}

function calculateAllSavings(){
    var allPossibilities = [];
    for(var i = 0; i < tours.length; i++){
        for(var j = 0; j < tours.length; j++){
            if(i != j)
            var savingObj = {saving:calculateSaving(tours[i],tours[j]), tourA: i, tourB: j};
                allPossibilities.push(savingObj);
        }
    }
    allPossibilities.sort(function(a, b){
        return b.saving-a.saving
    })  
    document.getElementById("demo3").innerHTML = "success";

    return allPossibilities;
}

//Initialize Array  
var tours = [];
tours.push([0,1,2,3,0]);
tours.push([0,4,5,6,0]);
tours.push([0,7,8,0]);
tours.push([0,9,10,0]);

//BUG
document.getElementById("demo1").innerHTML = tours.join('\n'); // Shows array correctly
var allSavings = calculateAllSavings(); //BUG APPEARS HERE
document.getElementById("demo2").innerHTML = tours.join('\n'); // Doesn't show anything

编辑解决: combine() 覆盖了原来的 tours[]。 通过与克隆之旅的结合,原版保持不变。

function combineTours(tourA, tourB){
    var tour1 = tourA.slice(0);
    var tour2 = tourB.slice(0);
    tour1.pop();
    tour2.shift();
    return tour1.concat(tour2);
}

感谢所有帮助过我的人

【问题讨论】:

  • 能否请您附上tourDist函数的代码?
  • 另外,你应该总是在条件后面加上 {} 来编写你的 if 语句,即使它是单行的。
  • @Gothdo 他的代码确实换行了(好吧,他故意把它放在下一行),因此我的评论。
  • 感谢您的回复。我添加了方法tourDist() 和euclDist()。抱歉格式不好,这是一次性使用的hacky代码,所以不需要可维护性......我怀疑它是缺少括号

标签: javascript sorting multidimensional-array


【解决方案1】:

好吧,在combineTours 函数中,您在一个数组上调用.pop() 方法,在另一个数组上调用.shift() 方法,这会从这些数组中的每一个中删除一个元素。在calculateAllSavings 中,您在循环中调用calculateSaving,它正在调用combineTours,因此您有效地从子数组中删除了所有元素。

也许您应该从combineTours 中删除这些行:

tourA.pop();
tourB.shift();

未来:使用console.log()进行调试,它可以帮助您识别问题。

【讨论】:

  • 您好,感谢您的回复。我需要 pop() 和 shift() 因为每个游览都需要在第一个和最后一个节点中有数字 0。因此,如果我有 tourA 01230 和 tourB 04560,它们应该合并为 01234560。
  • @Samuel 所以每次巡演只调用一次。
  • 所以你的回答让我走上了正确的道路:在 combineTours() 中,我克隆了 tourA 和 tourB 以及 .slice(0) ,因此原始的 tours[] 保持不变。非常感谢,我也会在原帖中编辑它
【解决方案2】:

你可以试试这个吗?

for(var i = 0; i < tours.length; i++){
        for(var j = 0; j < tours[i].length; j++){
            if(i != j)
            var savingObj = {saving:calculateSaving(tours[i],tours[j]), tourA: i, tourB: j};
                allPossibilities.push(savingObj);
        }
    }

除此之外,您还可以调试并查看您的 document.getElementById("demo2").innerHTML = tours.join('\n');行实际上被执行。您可能正在运行无限循环。尝试使用 chrome 开发人员工具调试您的代码。

【讨论】:

  • 您的内部 for 循环应该通过外部 for 循环。所以 j 应该通过 i 内的第一个数组,然后是第二个,然后是第三个。您所做的是,迭代 j 数组与 i 数组完全相同。所以内部值没有排序。
  • @Samuel :) 欢迎您。能否请您也接受我的回答?
  • 抱歉,我的回答有点太快了。我能够再次访问 tours[] 只是因为 j 循环中的语句从未执行过。这样calculateAllSavings() 提供一个空数组:-(
猜你喜欢
  • 1970-01-01
  • 2011-07-06
  • 2012-05-03
  • 1970-01-01
  • 1970-01-01
  • 2014-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多