范围问题,在另一个for循环中从一个for循环引用迭代器“ i”

时间:2019-05-17 13:37:12

标签: javascript jquery for-loop scope iterator

问题

我认为这两个for loops涉及范围问题。它们每个都迭代不同数量的项目。

  • 我正在尝试找出如何在第二个循环的第一个循环中引用i迭代器。
  • 具体地说,我在第二个循环的if语句的else部分中连接了一个字符串,我需要能够同时引用ij

澄清

我正在尝试创建一个11 x 8的网格,总计88个正方形。他们需要附加一个特定的类,这些类将为正方形着色。每个正方形都有一个从1到88的数据ID,用于确定它们在网格上的位置。在data.json代码段中可以看到,需要根据数据着色的状态/正方形不是连续的。

循环#1

i从0、1、2 ... 50开始

for (i = 0; i < data.length; i++) {}

第2圈

j从1、2、3 ... 88开始

for (j = 1; j < squaresTotal + 1; j++) {

    // If it doesn't exist, push those values into the an array
    if (states.indexOf(j) === -1){
        blanks.push(j);

        $("<div class='square is-white' data-id='" + j + "'></div>").appendTo(".map");
    } else {
        $("<div class='square " + data[i].class + "' data-id='" + j + "'><p class='square__state'>" + data[i].abbr + "</p></div>").appendTo(".map");
    }
}

scripts.js

<script>
        $(function(){
            $.ajax({
                url: 'data.json',
                method: 'GET',
                dataType: 'json'
            }).then(main);
        });

        function main(data) {

            // The parent container that holds the map
            let map = $(".map");

            // IDs of the states and the blank tiles
            let blanks = [];
            let states = [];

            // Contains data for all 50 states
            for (i = 0; i < data.length; i++) {

                // Data is sorted by the rank field in descending order
                data.sort(function(a, b){
                    return a['rank'] - b['rank'];
                });

                // Fields for the data table below the map
                // Numbered rank (i.e. 1, 2, 3)
                let rank = data[i].rank;

                // Full state name (i.e. Alaska)
                let state = data[i].state;

                // Total consumer electric power
                let value = (data[i].total_consumption_electric_power).toLocaleString();

                // Each row in the table contains a rank, state and value
                if (rank) {
                    $("<tr><th scope='row'>" + data[i].rank + "</th><td>" + data[i].state + "</td><td>" + value + "</td></tr>").appendTo("tbody");
                }

                // Push the ids to the empty states array
                states.push(data[i].id);
            }

            // The grid is 11 by 8 for a total of 88 squares
            const squaresTotal = 88;

            for (j = 1; j < squaresTotal + 1; j++) {

                // If it doesn't exist, push those values into the an array
                if (states.indexOf(j) === -1){
                    blanks.push(j);

                    $("<div class='square is-white' data-id='" + j + "'></div>").appendTo(".map");
                } else {
                    $("<div class='square " + data[i].class + "' data-id='" + j + "'><p class='square__state'>" + data[i].abbr + "</p></div>").appendTo(".map");
                }
            }

            var pymChild = new pym.Child();
            pymChild.sendHeight();
        }


    </script>

data.json(摘要)

[
  {
    "id": 1,
    "state": "Alaska",
    "rank": "",
    "abbr": "AK",
    "class": "square-1",
    "total_consumption_electric_power": 707913
  },
  {
    "id": 11,
    "state": "Maine",
    "rank": "",
    "abbr": "ME",
    "class": "square-1",
    "total_consumption_electric_power": 62360
  },
  {
    "id": 17,
    "state": "Wisconsin",
    "rank": "",
    "abbr": "WI",
    "class": "square-5",
    "total_consumption_electric_power": 19482575
  }
]

1 个答案:

答案 0 :(得分:1)

我简化了一些代码,以展示如何尝试构造代码。

如果您想使用JQuery进行渲染,则可以轻松地将其转换回去。

这不会回答您的索引i,索引j问题,因为您实际上不需要那些对我个人而言似乎更简单的方法。

var states = [
  {
    "id": 1,
    "state": "Alaska",
    "rank": 2,
    "abbr": "AK",
    "class": "square-1",
    "total_consumption_electric_power": 707913
  },
  {
    "id": 11,
    "state": "Maine",
    "rank": 3,
    "abbr": "ME",
    "class": "square-1",
    "total_consumption_electric_power": 62360
  },
  {
    "id": 17,
    "state": "Wisconsin",
    "rank": 1,
    "abbr": "WI",
    "class": "square-5",
    "total_consumption_electric_power": 19482575
  }
];

var render_rankings_table = function( states ) {
  // We want the table to be sorted by rank.
  // By creating a new array from the passed states array,
  // we retain the original order inside the states array.
  var sorted_by_rank = states.sort((a, b ) => a.rank - b.rank );
  // Create a row for each sorted_by_rank state.
  // Since this is a new array, we can just loop over it without affecting the original states array.
  var rows_html = sorted_by_rank.map( state => {
    return `<tr><td scope="row">${ state.rank }</td><td>${ state.state }</td><td>${ state.total_consumption_electric_power }</td></tr>`;
  });
  // Overwrite the content of the table to render it.
  // See how we update the table only once at the end instead of for every state individually.
  var table = document.querySelector( '#electric_consumption_ranking' );
  table.innerHTML = rows_html.join( '' );
};

// The original contains: if (states.indexOf(j) === -1){ blanks.push(j); }
// The states array contained all the id's.
// So translated, this means that the id of the state, equals the square it will render to.
// So Maine, with id 11, will be the eleventh square.
var render_squares = function( states ) {
  // Creating the 88 squares and mapping the states to it can be done in multiple ways.
  // I would prefer the 'easy' solution of just creating an array with 88 elements and
  // then putting the states in the correct position,
  // instead of figuring out the position of the state inside the loop.
  var squares = Array.from({ length: 88 }).fill( false );
  // We now have an array cotnaining 'false' 88 times.
  // Now lets add the states to it.
  // The squares start at 1, the array index starts at 0, so subtract 1 from the id to get the correct index.
  states.forEach( state => { squares[ state.id - 1 ] = state; });
  // Now all the states are in the correct position, according to their id.
  // Create the squares.
  var squares_html = squares.map(( state, index ) => {
    if ( state ) {
      return `<div class="square ${ state.class }" data-id="${ index + 1 }"><p class="square__state">${ state.abbr }</p></div>`;
    
    }
    // The data-ids start at 1, the array index starts at 0, so add 1 to the index.
    // The <div> has to have height to actually show up on the screen.
    // The easiest way is to make sure the div contains text, so adding a space already works.
    // We could also give the divs a minimum height with CSS.
    else {
      return `<div class='square is-white' data-id="${ index + 1 }">&nbsp;</div>`;
    }
  });
  // Overwrite the map.
  var map = document.querySelector( '.map' );
  map.innerHTML = squares_html.join( '' );
};

render_rankings_table( states );
render_squares( states );
table {
  border-collapse: collapse;
}

td {
  border: 1px solid grey;
}

.square {
  border-bottom: 1px solid grey;
  border-top: 1px solid grey;
}

.map {
  border: 1px solid grey;
}
.is-white {
  background-color: rgb( 238, 238, 238 );
}
.square-1 {
  background-color: red;  
}
.square-5 {
  background-color: green;
}
<table id="electric_consumption_ranking"></table>
<figure class="map"></figure>