3d数组覆盖来自其他维度JS的值

Posted

技术标签:

【中文标题】3d数组覆盖来自其他维度JS的值【英文标题】:3d Array Over-writing Values from other dimensions JS 【发布时间】:2014-08-22 08:42:06 【问题描述】:

我似乎无法弄清楚我昨天写的这段代码做错了什么。这是我第一次使用 javascript,也是第一次使用 jQuery 和 Node.js,我认为这个三维数组应该可以正常工作。我看到关于多维数组是什么的令人困惑的提及,人们说 JavaScript 没有,尽管它有数组的数组。无论如何,我想我在技术上使用的是一个数组的数组,并且不明白为什么我的外部数组(我认为它是设计上的外部维度)将两个内部数组中的元素覆盖到它自己的数组中元素。两个内部数组似乎按预期工作,但最外面的数组以某种我不太了解的方式混淆了数据。

可以通过滚动浏览此代码生成的 output.json 文件来观察不一致/问题,并看到输出显然与我正在抓取的此网页上的三个表中的每一个都不匹配:

// My server.js file:
var express = require('express');
var fs      = require('fs');
var request = require('request');
var cheerio = require('cheerio');
var app         = express();

// the link below is a tutorial I was loosely following
// see http://scotch.io/tutorials/javascript/scraping-the-web-with-node-js
app.get('/scrape', function(req, res) 

    url = 'http://espn.go.com/nba/player/stats/_/id/4145/kareem-abdul-jabbar'

    request(url, function(error, response, html) 

        if(!error) 

            // utilize the Cheerio library on the returned html, yielding jQuery functionality
            var $ = cheerio.load(html);

            var numOfRows;

            var stats = [[[]]];

            for(var chart = 0; chart < 3; chart++) 

                stats.push([[]]);   // allocates space for each grid on each chart (each set of rows and columns)

                $('.tablehead').eq(chart).filter(function()
                    var data = $(this);
                    numOfRows = data.children().length - 2;
                    for(var i = 0; i < numOfRows + 1; i++) 
                        stats[chart].push([]); // allocates space for each row in the chart
                    
                )

                var numOfColumns;

                $('.stathead').eq(chart).filter(function()
                    var data = $(this);
                    stats[chart][0][0] = data.children().first().text();
                )

                $('.colhead').eq(chart).filter(function()  // first() specifies to select the first of the three occurances of this class; use eq(param) to find the Nth occurance
                    var data = $(this);
                    numOfColumns = data.children().length; 
                    for(var i = 0; i < numOfColumns; i++) 
                        stats[chart][1][i] = data.children().eq(i).text();
                    
                )

                var currentRow = 2;

                for(var oddRow = 0; oddRow < (numOfRows + 1)/2 - 1; oddRow++) 
                    $('.tablehead .oddrow').eq(oddRow).filter(function()
                        var data = $(this);
                        for(var c = 0; c < numOfColumns; c++) 
                            stats[chart][currentRow][c] = data.children().eq(c).text();
                        
                        currentRow += 2;
                    )  
                   

                currentRow = 3;
                for(var evenRow = 0; evenRow < (numOfRows + 1)/2 - 1; evenRow++)
                    $('.tablehead .evenrow').eq(evenRow).filter(function()
                        var data = $(this);
                        for(var c = 0; c < numOfColumns; c++) 
                            stats[chart][currentRow][c] = data.children().eq(c).text();
                        
                        currentRow += 2;
                    )  
                

                currentRow -= 1; // gets the last allocated row index (after "currentRow += 2" has been executed)
                $('.tablehead .total').eq(chart).filter(function()
                    var data = $(this);
                    var LOGOIDX = 1;
                    for(var c = 0; c < numOfColumns - 1; c++) 
                        if(c < LOGOIDX) 
                            stats[chart][currentRow][c] = data.children().eq(c).text();
                        
                        if(c == LOGOIDX) 
                            stats[chart][currentRow][c] = "N.A.";
                            stats[chart][currentRow][c + 1] = data.children().eq(c).text();
                            continue;
                        
                        else 
                            stats[chart][currentRow][c + 1] = data.children().eq(c).text();
                        
                    
                )
               // end chart loop
        

    // Want to parse my json so that it displays in format: "name: value" rather than just "name" as it is now...

        fs.writeFile('output.json', JSON.stringify(stats, null, 4), function(err)

            console.log('File successfully written! - Check the project directory for the output.json file');
            console.log('Number of columns in chart is: ' + numOfColumns);
        )

        // message to browser reminding that there's no UI involved here.
        res.send('Check the console!')
    )
)

app.listen('8081')

console.log('Magic happens on port 8081');

exports = module.exports = app;

【问题讨论】:

输出是什么?输出有什么问题,你期望什么? 第一个猜测:你总是想要[](一个空数组),然后(在循环中,以编程方式)填充其他数组。 var stats = [[[]]]; // allocates space 听起来你习惯于“声明”它们是多维的。 嘿,抱歉,SO 新手,没有看到任何通知。我只是第一次使用 pastebin:pastebin.com/TXXEr11F。输出有点长,所以认为它在网上更好。当我抓取它时,您可以看到网站上第一个表中的数据 (espn.go.com/nba/player/stats/_/id/4145/kareem-abdul-jabbar) 在其他两个表中的数据内,例如:在我的 3d 数组中记录数据时,我忽略了一些可能很简单的事情。 但是输出看起来不错,不是吗?是不是记录了错误的数据?或者你想摆脱尾随的[[]] 嗯,我在最外层推送了 3 个空数组,在中间维度推送了 numOfRows 个空数组...对于 3d 数组,您是否建议我还需要推送第三个最内层维度的数组集?或者这会使它成为一个 4d 数组?我的初始化方式有问题吗? 【参考方案1】:

啊哈!抓住了我的错误——只是一个简单的逻辑错误。有点尴尬,我之前没有看到它,但是哦,好吧,在一天结束时进行了一些练习和研究(以及相当多的分心):

可以看出,我所做的所有对 HTML 类的搜索都是由一个名为“chart”的变量参数化的,除了我在每个图表中搜索奇数行和偶数行的地方——实际抓取的大部分每个图表,所以我的“3d 数组 [was] 覆盖了其他维度的值”

简单来说,我只需要根据每个图表的条件创建一个偏移量(几行额外的代码),我需要编辑两行代码来反映新计算的偏移量,如下所示:

$('.tablehead .oddrow').eq(rowOffset + oddRow).filter(function()

$('.tablehead .evenrow').eq(rowOffset + evenRow).filter(function()

无论如何感谢您的帮助!我希望这个问题对其他人大有裨益:P

【讨论】:

以上是关于3d数组覆盖来自其他维度JS的值的主要内容,如果未能解决你的问题,请参考以下文章

将来自 karma-coverage 的 istanbul 测试覆盖率与来自其他来源的覆盖率合并

Chrome DevTools:来自 Webpack Source Map 的 JS 文件的本地覆盖

从不同的 .js 文件中访问来自 1 个 .js 源文件 (jqTree) 的变量以覆盖方法

Object.assign() ,合并/覆盖键,复制数组的值以创建对象

bugku 变量覆盖

变量覆盖漏洞----extract()函数