#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