-1

I'm trying to populate an array of objects in Javascript. If I check the array item using the index immediately after pushing it onto the array it looks good. However, if I try to use the elements of the array after it is populated, the whole array seems to be populated with copies of the last object I pushed. I have the same problem in both Chrome and Firefox. I have attached a simplified version of my code that demonstrates the issue. Any guidance would be appreciated.

<script type="text/javascript">
  var JSONHLDat=[
  [
    "2",
    "1",
    "72.2",
    "52.1"
  ],
  [
    "2",
    "2",
    "72.2",
    "52.2"
  ],
  [
    "2",
    "3",
    "72.3",
    "52.4"
  ],
  [
    "2",
    "4",
    "72.4",
    "52.5"
   ]
  ];//data to be added to array
  var oHiLo ={
     oMonth: 0,
     oDay: 0,
     oHi: 0,
     oLo: 0
  };//oHiLo is the object

  var HiLo=[];//HiLo is the array to contain multiple oHiLo objects
  for (var j in JSONHLDat)
  {
      oHiLo.oMonth = JSONHLDat[j][0];
      oHiLo.oDay = JSONHLDat[j][1];
      oHiLo.oHi = JSONHLDat[j][2];
      oHiLo.oLo = JSONHLDat[j][3];
      console.log("oHiLo=", oHiLo);// here I display the object, it looks good.
      var ndx = HiLo.push(oHiLo);
      console.log("ndx=", ndx, " HiLo[(ndx-1)] = ", HiLo[(ndx - 1)]);//here I display the object in HiLo. It looks good.
   }
   for (var k=0;k<4;k++)
   {
       console.log("k=", k, "   HiLo[k] = ", HiLo[k]);// This appears to show that the array is populated with four copies of the last element pushed.
   }
</script>
chridam
  • 100,957
  • 23
  • 236
  • 235
  • Do `var oHiLo={oMonth:0,oDay:0,oHi:0,oLo:0};//oHiLo is the object` in loop – Benjamin Poignant Feb 23 '15 at 15:34
  • 2
    For starters, don't use `for-in` to loop through arrays (without safeguards); that's [not what it's for, and there are better ways](http://stackoverflow.com/questions/9329446/for-each-over-an-array-in-javascript/9329476#9329476). – T.J. Crowder Feb 23 '15 at 15:34

3 Answers3

1

You are changing the same oHiLo object over and over again.

Try the following (notice the definition of oHilo moved inside the cycle - it will create a new object in each cycle):

<script type="text/javascript">
var JSONHLDat=[["2","1","72.2","52.1"],["2","2","72.2","52.2"],["2","3","72.3","52.4"],["2","4","72.4","52.5"]];//data to be added to array
var HiLo=[];//HiLo is the array to contain multiple oHiLo objects
for (var j in JSONHLDat)
{
    var oHiLo = {oMonth:0,oDay:0,oHi:0,oLo:0};//oHiLo is the object
    oHiLo.oMonth=JSONHLDat[j][0];
    oHiLo.oDay=JSONHLDat[j][1];
    oHiLo.oHi=JSONHLDat[j][2];
    oHiLo.oLo=JSONHLDat[j][3];
    console.log("oHiLo=",oHiLo);// here I display the object, it looks good.
    var ndx=HiLo.push(oHiLo);
    console.log("ndx=",ndx,"    HiLo[(ndx-1)]=",HiLo[(ndx-1)]);//here I display the object in HiLo. It looks good.
}
for (var k=0;k<4;k++)
{
    console.log("k=",k,"   HiLo[k]=",HiLo[k]);// This appears to show that the array is populated with four copies of the last element pushed.
}
</script>

You may also use the map function:

<script type="text/javascript">
var JSONHLDat=[["2","1","72.2","52.1"],["2","2","72.2","52.2"],["2","3","72.3","52.4"],["2","4","72.4","52.5"]];//data to be added to array

var HiLo = JSONHLDat.map(function($data){
    return {
        oMonth: $data[0],
        oDay: $data[1],
        oHi: $data[2],
        oLo: $data[3]
    }
});

for (var k=0;k<4;k++)
{
    console.log("k=",k,"   HiLo[k]=",HiLo[k]);// This appears to show that the array is populated with four copies of the last element pushed.
}
</script>
BeS
  • 817
  • 4
  • 9
0

Declare var oHiLo={oMonth:0,oDay:0,oHi:0,oLo:0};//oHiLo is the object in the loop :

<script type="text/javascript">
var JSONHLDat=[["2","1","72.2","52.1"],["2","2","72.2","52.2"],["2","3","72.3","52.4"],["2","4","72.4","52.5"]];//data to be added to array
var HiLo=[];//HiLo is the array to contain multiple oHiLo objects
for (var j in JSONHLDat)
{
        var oHiLo={oMonth:0,oDay:0,oHi:0,oLo:0};//oHiLo is the object
        oHiLo.oMonth=JSONHLDat[j][0];
        oHiLo.oDay=JSONHLDat[j][1];
        oHiLo.oHi=JSONHLDat[j][2];
        oHiLo.oLo=JSONHLDat[j][3];
        var ndx=HiLo.push(oHiLo);
}
console.log(HiLo);
for (var k=0;k<4;k++)
{
        console.log("k=",k,"   HiLo[k]=",HiLo[k]);// This appears to show that the array is populated with four copies of the last element pushed.
}
</script>
Benjamin Poignant
  • 1,066
  • 8
  • 18
  • for-in loop is not intended for iterating through array items. – yas Feb 23 '15 at 15:40
  • @dave - The usage of for-in loop is not relevant to the question asked. This answers the question and resolves the problem. – BeS Feb 23 '15 at 15:45
0

There aren't four copies of the object in your array: just four references to the same object. That's because you're updating the object's properties in your loop but when you do

HiLo.push(oHiLo)

what happens is you're just pushing a reference to the object already referenced by oHiLo in the array.

What you should do is create a new object each time. Either use a litteral like this

HiLo.push({oMonth: JSONHLDat[j][0], oDay: JSONHLDat[j][1] …

or better, define a constructor for objects like oHiLo and then

HiLo.push(new oHiLo(JSONHLDat[j]))
Touffy
  • 6,309
  • 22
  • 28