Перезапись значений 3d-массива из других измерений JS

#javascript #jquery #arrays #node.js #multidimensional-array

#javascript #jquery #массивы #node.js #многомерный массив

Вопрос:

Кажется, я не могу понять, что я делаю не так в этом коде, который я написал вчера. Это был мой первый запуск 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;
  

Комментарии:

1. Каков результат? Что не так с выводом, чего вы ожидали?

2. Первое предположение: Вы всегда хотите [] (пустой массив), который затем позже (в цикле, программно) заполняется другими массивами. var stats = [[[]]]; // allocates space похоже, у вас вошло в привычку «объявлять» их как многомерные.

3. Эй, извините, новичок в SO и не видел никаких уведомлений. Я только что впервые использовал pastebin: pastebin.com/TXXEr11F . Вывод довольно длинный, поэтому подумал, что лучше онлайн. Вы можете увидеть данные в первой таблице на веб-сайте ( espn.go.com/nba/player/stats/_/id/4145/kareem-abdul-jabbar ) находится внутри данных в двух других таблицах, когда я их очистил, например: я пропускаю что-то, возможно, простое, при записи данных в мой 3D-массив.

4. Но результат выглядит неплохо, не так ли? Записываются ли неправильные данные? Или вы хотите избавиться от конечного [[]] ?

5. Хм, я вставил 3 пустых массива во внешнее измерение и вставил пустые массивы numOfRows в среднее измерение… Вы предполагаете, что для 3D-массива мне также нужно будет вставить третий набор массивов в самое внутреннее измерение? Или это сделало бы его массивом 4d? Что-то не так в том, как я инициализирую?

Ответ №1:

Ага! Поймал мою ошибку — просто простая логическая ошибка. Немного неловко, что я не видел этого раньше, но что ж, к концу дня я немного попрактиковался и изучил (и изрядно отвлекся):

Как можно видеть, весь поиск HTML-классов, который я выполнял, был параметризован переменной с именем «chart», за исключением того, где я искал нечетные и четные строки внутри каждой диаграммы — фактическая очистка основной части каждой диаграммы, поэтому наивно казалось, что мой «3d-массив [был] перезаписью значений из других измерений» <- lol.

Проще говоря, мне просто нужно было создать смещение на основе условия для каждой диаграммы (несколько дополнительных строк кода), и мне нужно было отредактировать две строки кода, чтобы отразить вновь вычисленное смещение следующим образом:

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

и

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

В любом случае спасибо за любую помощь! Я надеюсь, что эта проблема существенно поможет другим: P