简体   繁体   中英

Counting and looping through multiple arrays within object

I'm basically just trying to loop through a series of arrays (dynamically created) and output the results in the console. The debugger is telling me that this.allitems[i] is undefined. How do I loop through each array in the allItems object?

var warehouse = {
  allItems: {
    shirts:[],
    shorts:[]
  },

 // Counts how many arrays are in the object 
 countArraysInAllItems: function(obj){
    var size = 0,key;
    for(key in obj){
      if(obj.hasOwnProperty(key)) size++;
    }
    return size;
  },

  // Display the items from the arrays (in no particular order)
  displayItems: function(){
    var allItemsLength = this.countArraysInAllItems(this.allItems);

    for(var i=0; i<allItemsLength; i++){
      var itemSubArray = this.allItems[i];

      for(var j=0; j<itemSubArray.length; j++){
        var itemType = this.itemSubArray[j].itemType;
        var itemName = this.itemSubArray[j].itemName;
        var itemQuantity = this.itemSubArray[j].itemQuantity;

        console.log('Type:' + itemType + '\n' + 
                  'Name: ' + itemName + '\n' +  
                  'Qty:' + itemQuantity);
        }
      }
    }

The problem is that a traditional for loop in JS can be used to loop over an array but not an object . If you think about it, it makes sense-- no property in the object is at a specific index per se.

What you're looking for is the for...in loop -- you're already using it for the count, but then for some reason abandon it in your later loop.

Try something like this-- I couldn't test it with the incomplete code/dataset, but I think it'll be closer to what you're looking to accomplish (and you may not even need the countArraysInAllItems method anymore):

var warehouse = {
  allItems: {
      shirts: [],
      shorts: []
  },

  // Counts how many arrays are in the object 
  countArraysInAllItems: function(obj) {
      var size = 0,
          key;
      for (key in obj) {
          if (obj.hasOwnProperty(key) && Array.isArray(obj[key])) {
            size++;
          }
      }
      return size;
  },

  // Display the items from the arrays (in no particular order)
  displayItems: function() {
      var allItemsLength = this.countArraysInAllItems(this.allItems);
      var key;
      var j;
      var itemSubArray;
      var itemType;
      var itemName;
      var itemQuantity;

      for (key in this.allItems) {

          if (obj.hasOwnProperty(key) && Array.isArray(obj[key])) {

            itemSubArray = obj[key];

            for (j = 0; j < itemSubArray.length; j++) {
                itemType = this.itemSubArray[j].itemType;
                itemName = this.itemSubArray[j].itemName;
                itemQuantity = this.itemSubArray[j].itemQuantity;

                console.log('Type:' + itemType + '\n' +
                    'Name: ' + itemName + '\n' +
                    'Qty:' + itemQuantity);
            }

          }

      }
  }
};

PS - I made a few other small changes-- firstly, I moved all the var declarations to the top of the function scope to manage hoisting , and I also included a check to ensure the property of the allItems object is, in fact, an array (just in case you were planning on storing other things on the object).

As stated by other answers, allItems is an object, so you cannot iterate in it as an array.

Here is my solution, with 2 for..in loops, making the code less verbose :

var warehouse = {
  allItems: {
    shirts:[
      {
        itemType: "type1",
        itemName: "shirt1",
        itemQuantity: 1
      },
      {
      itemType: "type2",
      itemName: "shirt2",
      itemQuantity: 10
    }
    ],
    shorts:[
      {
        itemType: "type3",
        itemName: "short1",
        itemQuantity: 4
      }
    ]
  },

// Counts how many arrays are in the object 
countArraysInAllItems: function(obj){
    var size = 0,key;
    for(key in obj){
      if(obj.hasOwnProperty(key)) size++;
    }
    return size;
  },

  // Display the items from the arrays (in no particular order)
  displayItems: function(){
    // this variable is not useful right now
    var allItemsLength = this.countArraysInAllItems(this.allItems);

    for(var i in this.allItems){
      var itemSubArray = this.allItems[i];

      for(var j in itemSubArray){
        var itemType = itemSubArray[j].itemType;
        var itemName = itemSubArray[j].itemName;
        var itemQuantity = itemSubArray[j].itemQuantity;

        console.log('Type:' + itemType + '\n' + 
                  'Name: ' + itemName + '\n' +  
                  'Qty:' + itemQuantity);
      }
    }
  }
}

If you're married to using a for.. loop, you could do it like so:

var warehouse = {
  allItems: {
    shirts:{itemType:"type1", itemName:"name1", itemQuantity:"qty1"},
    shoes:{itemType:"type2", itemName:"name2", itemQuantity:"qty2"}
  },

  // Display the items from the arrays (in no particular order)
  displayItems: function(){
      for (var item in this.allItems) {
        console.log(item);
        var itemType = this.allItems[item].itemType;
        var itemName = this.allItems[item].itemName;
        var itemQuantity = this.allItems[item].itemQuantity;
        console.log('Type: ' + itemType + '\n' +
                  'Name: ' + itemName + '\n' +
                  'Qty: ' + itemQuantity);
      }
    }
}

warehouse.displayItems();

Othewrwise, you can (and should) iterate through the Object.keys() as recommended by others.

You can use for..in loop. A first loop for allTtems property and another nested loop for the arrays shirts and shorts :

var warehouse = {
  allItems: {
    shirts:[1,2,3,],
    shorts:[10,11,12]
  }
};
for (var item in warehouse)
  for (var element in warehouse[item])
     console.log(warehouse[item][element]);
// [ 1, 2, 3 ]
// [ 10, 11, 12 ]

You can use

    Object.keys(this.allItems).forEach(item => {
      console.log(item);
    });

More precise answer

  const warehouse = {
    allItems: {
        shirts: [
            {
                itemType: '1',
                itemName: '2',
                itemQuantity: '3',
            }
        ],
        shorts: [
            {
                itemType: '5',
                itemName: '6',
                itemQuantity: '7',
            }
        ]
    },

    // Display the items from the arrays (in no particular order)
    displayItems: function() {
        Object.keys(this.allItems).forEach(items => {
            Object.keys(this.allItems[items]).forEach(item => {
                const {itemType, itemName, itemQuantity} = this.allItems[items][item];
                console.log(itemType, itemName, itemQuantity);
            });
        });
    }
  }

Iterate the object using Object.keys() and Array.prototype.forEach() . Then use forEach() to iterate each array:

 var warehouse = { allItems: { shirts: [{ itemType: "type1", itemName: "shirt1", itemQuantity: 1 }, { itemType: "type2", itemName: "shirt2", itemQuantity: 10 }], shorts: [{ itemType: "type3", itemName: "short1", itemQuantity: 4 }] }, displayItems: function() { var items = this.allItems; Object.keys(items).forEach(function(key) { items[key].forEach(function(item) { console.log('Type:' + item.itemType + '\\n' + 'Name: ' + item.itemName + '\\n' + 'Qty:' + item.itemQuantity); }); }); } }; warehouse.displayItems(); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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