简体   繁体   English

如何访问嵌套数组的值?

[英]How to access values of nested arrays?

I have an array inside an array of objects that I want to retrieve a property from. 我要从中检索属性的对象数组中有一个数组。 I've accomplished it here , but it seems clunky. 我已经在这里完成 ,但是似乎很笨拙。 Is there a better way of looping through each StaffList array within each room? 有没有更好的方法遍历每个房间中的每个StaffList数组?

window.onload = getInitials;
var data = {
    "room" : [
        {
            "id" : 1,
            "StaffList": [
                {                  
                  "inroom": true,                  
                  "initials": "MG"
                },
                {
                  "inroom": false,
                  "initials": "CT"
                },
                {
                  "inroom": true,
                  "initials": "MS"
                }
            ]
        },
        {
            "id" : 2,
            "StaffList": [
                {                  
                  "inroom": true,                  
                  "initials": "MG"
                },
                {
                  "inroom": false,
                  "initials": "CT"
                },
                {
                  "inroom": true,
                  "initials": "MS"
                },
                {
                  "inroom": true,
                  "initials": "MA"
                }
            ]
        }   

    ]
}

function getInitials() {
    var len = data.room.length;
    for(i = 0; i < len; i++) {
        var staffArray = data.room[i].StaffList;
        var room = data.room[i].id;
        if( staffArray != null ) {
            var allStaff = staffArray.filter(function(person) {
                if ( person.initials ) {
                    var inits = person.initials;
                    setInitials(room, inits);
                }
            });
        }
    }
}

function setInitials(room, initials) {
    //get element by ID
    //var staffContainer = $('#div' + room);
    var staffContainer = document.getElementById('div' + room);
    if(staffContainer != null) {
        //create new div to append
        var newDiv = document.createElement('div');
        newDiv.innerHTML = initials; 
        //append newly created <div>
        staffContainer.append(newDiv);
    }
}

You could use some forEach : 您可以使用一些forEach

data.room.forEach(function(room) {
  room.StaffList.forEach(function(person) {
    setInitials(room.id, person.initials);
  });
});

Here, we first loop through each room and then through each person of the StaffList . 在这里,我们首先遍历每个room ,然后遍历StaffList每个person Since the second forEach is inside the first one, we have access to its scope (through a closure, see How do JavaScript closures work? ). 由于第二个forEach 位于第一个中,因此我们可以访问其范围(通过闭包,请参阅JavaScript闭包如何工作? )。 Then we can just employ our new parameters, room and person , for setInitials . 然后我们可以为setInitials使用新的参数roomperson

Notice how there was no use of a var statement. 注意如何不使用var语句。 When you don't need to create a state (a variable), don't do it. 当您不需要创建状态(变量)时,请不要这样做。 Fewer states generally also mean fewer errors. 更少的状态通常也意味着更少的错误。 However, in your setInitials function, the use of states for the container and the new div is the way to go. 但是,在setInitials函数中,必须使用容器和新div的状态。

PS: Something else about your code tickles me. PS:关于您的代码的其他事情让我很烦。 Your variable room is not a room object, but an id. 您的可变room不是房间对象,而是ID。 It's misleading! 这是误导! Make sure to use the right name for the right thing. 确保为正确的事物使用正确的名称。 Here, if you want a state to store the id of a room, name it roomId . 在这里,如果要让状态存储房间的ID,则将其命名为roomId


You said in a comment that you also wanted to add a class on the created div if the inroom value is true (by the way, you should CamelCase it). 您在评论中说,如果inroom值为true,则还希望在创建的div上添加一个类(顺便说一句,您应该使用CamelCase )。 In that case, you could pass it as third parameter of setInitials , then add the class according to its value in the body of the function. 在这种情况下,您可以将其作为setInitials第三个参数传递,然后根据其值在函数主体中添加类。

Without any real details on how you want to sort things: just use sort with a sorting function, it's what it was designed for (noting that sort() is in-place , it modifies the array that's being sorted instead of merely generating a new array as function output): 没有关于如何排序的任何实际细节:仅将sort与排序函数一起使用,这就是它的设计目的(请注意sort() 就位 ,它修改了要排序的数组,而不仅仅是生成一个新数组数组作为函数输出):

var data = ....;

// preprocess your data
data.rooms.forEach(function(room) {
  doSomethingToYour(room);
});

// sort stafflists per room, which we can only do
// after your preprocessing has completed.
data.rooms.forEach(function(room) {
  room.StaffList.sort(function(a,b) {
    a = a.initials;
    b = b.initials;
    return a<b? -1 : a>b ? 1 : 0;
  });
});

// optionally, we can sort the rooms now, if those
// relied on ordered StaffList. If not, we could have
// sorted them at any point.
data.rooms.sort(function(a,b) {
  return b.id - a.id;
}); 

A couple suggestions: 几个建议:

Use nested loops to retrieve nested array values 使用嵌套循环检索嵌套数组值

This one's pretty simple: your outer loop will traverse the array of rooms, while your inner loop will traverse the array of staff for each room. 这很简单:您的外循环将遍历所有房间,而内循环将遍历每个房间的员工。

In the example code below, my outer loop is a while loop and my inner is a for , but you can of course accomplish it using whichever method you prefer. 在下面的示例代码中,我的外部循环是while循环,而内部循环是for ,但是您当然可以使用任何喜欢的方法来完成它。

function getInitials() {
  var len = data.room.length;
  while (len--) {
    var staffArray = data.room[len].StaffList;
    var room = data.room[len].id;
    for (var i = 0; i < staffArray.length; i++) {
      var person = staffArray[i];
      if (person.initials) {
        setInitials(room, person.initials);
      }
    }
  }
}

function setInitials(room, initials) {
  var staffContainer = document.getElementById("div" + room);
  if (staffContainer != null) {
    var newDiv = document.createElement("div");
    newDiv.innerHTML = initials;
    staffContainer.appendChild(newDiv);
  }
}

Reduce unnecessary DOM queries 减少不必要的DOM查询

I recommend caching an array of references to the desired divs, so you can just use the div's index in the array to retrieve it. 我建议缓存对所需div的引用数组,因此您可以只使用数组中div的索引来检索它。

I would do this by populating the array of divs in the outer loop, then passing the relevant div as the first argument to setInitials() 我将通过在外部循环中填充div数组,然后将相关的div作为第一个参数传递给setInitials()

 function getInitials() { var len = data.room.length; var roomDivs = []; while (len--) { var staffArray = data.room[len].StaffList; var roomId = data.room[len].id; roomDivs[roomId] = document.getElementById("div" + roomId); for (var i = 0; i < staffArray.length; i++) { var person = staffArray[i]; if (person.initials) { setInitials(roomDivs[roomId], person.initials); } } } } function setInitials(staffContainer, initials) { if (staffContainer != null) { var newDiv = document.createElement("div"); newDiv.innerHTML = initials; staffContainer.appendChild(newDiv); } } var data = { "room": [{ "id": 1, "StaffList": [{ "inroom": true, "initials": "MG" }, { "inroom": false, "initials": "CT" }, { "inroom": true, "initials": "MS" }] }, { "id": 2, "StaffList": [{ "inroom": true, "initials": "MG" }, { "inroom": false, "initials": "CT" }, { "inroom": true, "initials": "MS" }, { "inroom": true, "initials": "MA" }] } ] } getInitials(); 
 #div1 { background-color: burlywood; } #div2 { background-color: crimson; } div { height: auto; width: 50px; padding: 3px; margin: 2px; } 
 <div id="div1"></div> <div id="div2"></div> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM