Search code examples
javascriptarraysobjectmultidimensional-arrayjavascript-objects

Reduce JS object array with same DateTime into new object array with new fields


I'm having JS object array

var data = [
    {
        "TagName": "<DanPac_A>.<Daniel.DanOPCHub>.<FT35101A.Blocks_127.ProfileFactor>",
        "TagValue": 0.28503300001757387,
        "TimeStamp": "2022-11-01T00:00:00+00:00"
    },
    {
        "TagName": "<DanPac_A>.<Daniel.DanOPCHub>.<FT35101A.Blocks_127.Symmetry>",
        "TagValue": 0.3287246675158156,
        "TimeStamp": "2022-11-01T00:00:00+00:00"
    },
    {
        "TagName": "<DanPac_A>.<Daniel.DanOPCHub>.<FT35101A.Blocks_127.ProfileFactor>",
        "TagValue": 0.5102929393885312,
        "TimeStamp": "2022-11-01T00:05:00+00:00"
    },
    {
        "TagName": "<DanPac_A>.<Daniel.DanOPCHub>.<FT35101A.Blocks_127.Symmetry>",
        "TagValue": 0.839778175550664,
        "TimeStamp": "2022-11-01T00:05:00+00:00"
    },
    {
        "TagName": "<DanPac_A>.<Daniel.DanOPCHub>.<FT35101A.Blocks_127.Symmetry>",
        "TagValue": 0.6645055040936911,
        "TimeStamp": "2022-11-01T00:10:00+00:00"
    },
    {
        "TagName": "<DanPac_A>.<Daniel.DanOPCHub>.<FT35101A.Blocks_127.ProfileFactor>",
        "TagValue": 0.7310429668316368,
        "TimeStamp": "2022-11-01T00:10:00+00:00"
    },
    {
        "TagName": "<DanPac_A>.<Daniel.DanOPCHub>.<FT35101A.Blocks_127.ProfileFactor>",
        "TagValue": 0.7307108255629555,
        "TimeStamp": "2022-11-01T00:15:00+00:00"
    }
]

I want to reduce this array and change property response in such a way, if TagName has ProfileFactor it should represent as x : TagValue and if TagName has Symmetry it should represent as y: TagValue and combined with similar date time

expected output

result = [{
    "TimeStamp": "2022-11-01T00:00:00+00:00",
  "x": 0.28503300001757387,
  "y": 0.3287246675158156
}, {
    "TimeStamp": "2022-11-01T00:05:00+00:00",
  "x":0.5102929393885312,
  "y":0.839778175550664
}, {
    "TimeStamp": "2022-11-01T00:10:00+00:00",
  "x":0.7310429668316368,
  "y":0.6645055040936911
}]

Solution

  • Here is a solution using reduce and filter. In the reduce step groups by timestamp to an object of timestamp as keys and then converts to an array of the values for each key.
    Next filter the elements having both x and y

    I could have used .filter(({x,y}) => x && y) but it would then exclude if both x and y happen to be 0

    var data = [    {        "TagName": "<DanPac_A>.<Daniel.DanOPCHub>.<FT35101A.Blocks_127.ProfileFactor>",        "TagValue": 0.28503300001757387,        "TimeStamp": "2022-11-01T00:00:00+00:00"    },    {        "TagName": "<DanPac_A>.<Daniel.DanOPCHub>.<FT35101A.Blocks_127.Symmetry>",        "TagValue": 0.3287246675158156,        "TimeStamp": "2022-11-01T00:00:00+00:00"    },{        "TagName": "<DanPac_A>.<Daniel.DanOPCHub>.<FT35101A.Blocks_127.ProfileFactor>",        "TagValue": 0.5102929393885312,        "TimeStamp": "2022-11-01T00:05:00+00:00"    },    {        "TagName": "<DanPac_A>.<Daniel.DanOPCHub>.<FT35101A.Blocks_127.Symmetry>",       "TagValue": 0.839778175550664,       "TimeStamp": "2022-11-01T00:05:00+00:00"    },    {        "TagName": "<DanPac_A>.<Daniel.DanOPCHub>.<FT35101A.Blocks_127.Symmetry>",        "TagValue": 0.6645055040936911,        "TimeStamp": "2022-11-01T00:10:00+00:00"    },    {        "TagName": "<DanPac_A>.<Daniel.DanOPCHub>.<FT35101A.Blocks_127.ProfileFactor>",        "TagValue": 0.7310429668316368,        "TimeStamp": "2022-11-01T00:10:00+00:00"    },    {        "TagName": "<DanPac_A>.<Daniel.DanOPCHub>.<FT35101A.Blocks_127.ProfileFactor>",        "TagValue": 0.7307108255629555,        "TimeStamp": "2022-11-01T00:15:00+00:00"  }]
    
    
    const res = Object.values(data.reduce((acc,{TagName,TagValue,TimeStamp}) => {
      acc[TimeStamp] ??= {TimeStamp}
      acc[TimeStamp][TagName.includes("ProfileFactor") ? "x" : "y"] = TagValue
      return acc
    },{})).filter(obj => obj.hasOwnProperty('x') && obj.hasOwnProperty('y'))
    
    console.log(res)