简体   繁体   中英

Transform Array of object using Lodash groupby and map

Here is what I want to do, I want to take the following array and turn it into the array after it. Can anyone point me in the right direction?

Original Data

[{
        "FeatureId": 1,
        "District": "ANE",
        "Temperature": 206,
        "RelativeHumidity": 20,
        "WindSpeed": 5,
        "WindGust": 15
      },
      {
        "FeatureId": 1,
        "District": "ANE",
        "Temperature": 196,
        "RelativeHumidity": 19,
        "WindSpeed": 5,
        "WindGust": 15
      },
      {
        "FeatureId": 2,
        "District": "AMO",
        "Temperature": 203,
        "RelativeHumidity": 54,
        "WindSpeed": 9,
        "WindGust": 18
      },
      {
        "FeatureId": 2,
        "District": "AMO",
        "Temperature": 184,
        "RelativeHumidity": 46,
        "WindSpeed": 12,
        "WindGust": 18
      }]

My Desired Data :

[
  {
    "FeatureId": 1,
    "District": "ANE",
    "TemperatureTrend": [ 206, 196 ],
    "RelativeHumidityTrend": [ 20, 19 ],
    "WindSpeedTrend": [ 5, 5 ],
    "WindGustTrend": [ 15, 15 ]
  },
  {
    "FeatureId": 2,
    "District": "AMO",
    "TemperatureTrend": [ 203, 184 ],
    "RelativeHumidityTrend": [ 54, 46 ],
    "WindSpeedTrend": [ 9, 12 ],
    "WindGustTrend": [ 18, 18 ]
  },

]

I have tried combining groupby and map, but I was unable to resolve the issue. I was also unsure how to log the steps.

Apart from other good answers, you can use es6 destructuring as well.

 var arr = [{ "FeatureId": 1, "District": "ANE", "Temperature": 206, "RelativeHumidity": 20, "WindSpeed": 5, "WindGust": 15 }, { "FeatureId": 1, "District": "ANE", "Temperature": 196, "RelativeHumidity": 19, "WindSpeed": 5, "WindGust": 15 }, { "FeatureId": 2, "District": "AMO", "Temperature": 203, "RelativeHumidity": 54, "WindSpeed": 9, "WindGust": 18 }, { "FeatureId": 2, "District": "AMO", "Temperature": 184, "RelativeHumidity": 46, "WindSpeed": 12, "WindGust": 18 }] var temp = arr.reduce((o, d) => ( { WindSpeed, WindGust, RelativeHumidity, Temperature, ...rest } = ({ ...d , ...{ RelativeHumidityTrend: (o[d.FeatureId] && o[d.FeatureId].RelativeHumidityTrend || []).concat(d.RelativeHumidity) , WindSpeedTrend: (o[d.FeatureId] && o[d.FeatureId].WindSpeedTrend || []).concat(d.WindSpeed) , WindGustTrend: (o[d.FeatureId] && o[d.FeatureId].WindGustTrend || []).concat(d.WindGust) , TemperatureTrend: (o[d.FeatureId] && o[d.FeatureId].TemperatureTrend || []).concat(d.Temperature) } }) , o[d.FeatureId] = rest , o ) , {}) var result = Object.values(temp) console.log(result) 

Lets use Array.prototype.reduce because it fit the purpose of what you are trying to do.

    const data = [{
        "FeatureId": 1,
        "District": "ANE",
        "Temperature": 206,
        "RelativeHumidity": 20,
        "WindSpeed": 5,
        "WindGust": 15
      },
      {
        "FeatureId": 1,
        "District": "ANE",
        "Temperature": 196,
        "RelativeHumidity": 19,
        "WindSpeed": 5,
        "WindGust": 15
      },
      {
        "FeatureId": 2,
        "District": "AMO",
        "Temperature": 203,
        "RelativeHumidity": 54,
        "WindSpeed": 9,
        "WindGust": 18
      },
      {
        "FeatureId": 2,
        "District": "AMO",
        "Temperature": 184,
        "RelativeHumidity": 46,
        "WindSpeed": 12,
        "WindGust": 18
      }]

// we gonna create from scratch array and populate it
const aggregatedData = data.reduce((memo, element) => {
  const featureId = element.FeatureId

  const elementIndex = memo.findIndex(el => el.FeatureId === featureId)
  if (elementIndex === -1) {
    memo.push({
      FeatureId: featureId,
      District: element.District,
      TemperatureTrend: [element.Temperature],
      RelativeHumidityTrend: [element.RelativeHumidity],
      WindSpeedTrend: [element.WindSpeed],
      WindGustTrend: [element.WindGust]
    })
  } else {
    memo[elementIndex].TemperatureTrend.push(element.Temperature)
    memo[elementIndex].RelativeHumidityTrend.push(element.RelativeHumidity)
    memo[elementIndex].WindSpeedTrend.push(element.WindSpeed)
    memo[elementIndex].WindGustTrend.push(element.WindGust)
  }

  return memo
}, [])

console.log(aggregatedData)

You can check it in codepen

Christian, welcome to StackOverflow!

You have an interesting, multi-step logic problem. I am assuming you may have more than just 2 of each FeatureId, and in fact I will assume you could have anywhere from 1...n of FeatureId.

I would first use a forEach loop to make an array of all your unique FeatureId values. Then, now knowing what those values are, I would use JavaScript's filter to create a new array that contains only those objects with the same FeatureId.

The last step, combining the objects, will be much easier now that all elements in these "working arrays" have the same FeatureId. If there is only one observation object, you can push the existing object onto a final, finished array. If there is >1 observation object, then you can use your combining logic and push a new concatenated object onto your final, finished array.

Your idea of using lodash map is headed in the right direction, but 1) see if you can do it without Lodash and 2) I think a combination of filter and forEach will work better for you.

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