简体   繁体   中英

Replacing an element of an Array at a specific index

I have two datasets. One is an array of strings, and the other one is an array of objects.

I am trying to...

  1. Find the index of an item in an array

  2. And then replace the item with another item in the array of that index

But I can't get it to work on here - https://jsfiddle.net/jt100/pbL2vyn4/7/ . ( HELP !)

  
  
 let weeklyDates = [
    "2020-12-21",
    "2020-12-22",
    "2020-12-23",
    "2020-12-24",
    "2020-12-25",
    "2020-12-26",
    "2020-12-27"
  ]
  
  let sitesID = ["1_STANNARY", "3_FOXCAFE"]


let hourlyWastes = [
{
  "hourlyWaste": [
    {
      "coverWaste": [
        10
      ],
      "Date": "2020-12-12",
      "dayOfYear": "347",
      "preparationWaste": [
        10
      ],
      "spoilageWaste": [
        10
      ]
    }
  ],
  "siteName": "1_STANNARY"
}, 
{
  "hourlyWaste": [
    {
      "coverWaste": [
                20
      ],
      "Date": "2020-12-23",
      "dayOfYear": "358",
      "preparationWaste": [
                20
      ],
      "spoilageWaste": [
        20
      ]
    }
  ],
  "siteName": "3_FOXCAFE"
}, 
]
  
 let hourlyWastesWeeklyDates = []
 
 let num;
 for (num = 0; num < weeklyDates.length; num++) {
   hourlyWastes.map((data) => {
    data.hourlyWaste.filter((item) =>{      
      if (item.Date == weeklyDates[num]) {
        let hourlyWastes = {
          siteId: data.siteName,
          date: item.Date,
          data: {
            "coverWaste": item.coverWaste,
            "preparationWaste": item.preparationWaste,
            "spoilageWaste": item.spoilageWaste
          }
        }
        hourlyWastesWeeklyDates.push(hourlyWastes)
      }
    })
   })
 };    



let sitesWeeklyDate = []
sitesID.map((data) => {
    let siteIdDate = {
    weeklyDates: weeklyDates,
    siteID: data
  }

  sitesWeeklyDate.push(siteIdDate)
})
 


hourlyWastesWeeklyDates.map((data) => {
  sitesWeeklyDate.filter((item, iNum) => {
    if (item.siteID === data.siteId && item.weeklyDates.includes(data.date)) {
    let indexNum = item.weeklyDates.indexOf(data.date)    
    sitesWeeklyDate[iNum].weeklyDates[indexNum] = data.data
    }
  })
})

console.log("sitesWeeklyDate",sitesWeeklyDate)     

Could you please advise why it is not working?

I am getting the code return below in my console.log which is wrong because the date value "2020-12-12", from siteID "1_STANNARY", do not exists in the weeklyDates array therefore it should not assign an object to replace the date value "2020-12-23"

sitesWeeklyDate = [
 {
   siteID: "1_STANNARY", 
   weeklyDates: ["2020-12-21", "2020-12-22", {…}, "2020-12-24", "2020-12-25", "2020-12-26", "2020-12-27"]
 },
  {
   siteID: "3_FOXCAFE", 
   weeklyDates: ["2020-12-21", "2020-12-22", {…}, "2020-12-24", "2020-12-25", "2020-12-26", "2020-12-27"]
 }

the correct return from console.log should be

sitesWeeklyDate = [
 {
   siteID: "1_STANNARY", 
   weeklyDates: ["2020-12-21", "2020-12-22", "2020-12-23", "2020-12-24", "2020-12-25", "2020-12-26", "2020-12-27"]
 },
  {
   siteID: "3_FOXCAFE", 
   weeklyDates: ["2020-12-21", "2020-12-22", {…}, "2020-12-24", "2020-12-25", "2020-12-26", "2020-12-27"]
 }

Thank you!

It may be an array reference related issue.

Try the following:

sitesID.map((data) => {
    let siteIdDate = {
        weeklyDates: Array.from(weeklyDates), //<-- This.
        siteID: data
    }
    sitesWeeklyDate.push(siteIdDate)
})

The problem you pinpoint in your question originates here:

let sitesWeeklyDate = []
sitesID.map((data) => {
    let siteIdDate = {
        weeklyDates: weeklyDates,
        siteID: data
    }
    sitesWeeklyDate.push(siteIdDate)
})

In this loop you assign one single array to each siteIdDate.weeklyDates property. So you are pushing to sitesWeeklyDate objects which each refer the same array via their weeklyDates property. Later you do the following:

sitesWeeklyDate[iNum].weeklyDates[indexNum] = data.data

You mutate that single array, and so the effect will be equally visible in sitesWeeklyDate[0] , sitesWeeklyDate[1] , ...etc.

In short, you can solve this in the earlier quoted code, by making this change:

    let siteIdDate = {
        weeklyDates: [...weeklyDates], // <--- copy the array
        siteID: data
    }

I didn't look at any other logic in your code, so this might not prevent other problems from occurring, but it solves the issue at hand.

Some remarks

  • Don't use .map when you don't use its return value. .map is intended to...map, not just iterate. And actually, in the above example, you should use that power. You can then also use the arrow-function-expression syntax. And why not name the callback parameter siteId so you can use the shortcut property syntax. It could become:

     let sitesWeeklyDate = sitesID.map((siteID) => ({ weeklyDates: [...weeklyDates], siteID }));
  • Another concern is that you assign with = data.data in a loop. This again can cause a similar problem (if you later mutate that single object). You might need to change that to = {...data.data} to again take a copy . You need to be careful with assigning objects/arrays when you plan to later mutate them.

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