2

Trying creating array of objects based on another array of objects. Decided to use flatmap and then reduce, but the problem is when I have more than one object in result array - I can not collected several statuses in one object. Have added what i tried and what is result I am trying to achieve.

What I have

const data = [
    {
        "timestamp": "2021-08-31T15:29:18Z",
        "result": [
            {
                "label": "Not Covered",
                "value": 132
            }
        ]
    },
    {
        "timestamp": "2021-09-30T15:29:18Z",
        "result": [
            {
                "label": "Not Covered",
                "value": 135
            }
        ]
    },
    {
        "timestamp": "2021-10-31T16:29:18Z",
        "result": [
            {
                "label": "Not Covered",
                "value": 135
            }
        ]
    }
]

What I need to get

[
    {
        "Not Covered":132,
        "Active":0,
        "Expiring Soon":0,
        "timestamp": "2021-08-31T15:29:18Z"
    },
    {
        "Not Covered":135,
        "Active":0,
        "Expiring Soon":0,
        "timestamp": "2021-09-30T15:29:18Z"
    },
    {
        "Not Covered":135,
        "Active":0,
        "Expiring Soon":0,
        "timestamp": "2021-10-31T16:29:18Z"
    }
]

What I am doing

let flattenedResult = data.flatMap(({result,...r}) => result.map(o => ({ ...o,...r})));

const chartData = flattenedResult.reduce((acc, item) => {
    const {timestamp, value,label} = item;

    acc.push({timestamp, "Not Covered":"Not Covered"===label?value:0,"Active":"Active"===label?value:0,"Expiring Soon":"Expiring Soon"===label?value:0});
    return acc;
  }, []); 

What i am getting:

[
    {
        "timestamp": "2021-08-31T15:29:18Z",
        "Not Covered": 132,
        "Active": 0,
        "Expiring Soon": 0
    },
    {
        "timestamp": "2021-09-30T15:29:18Z",
        "Not Covered": 135,
        "Active": 0,
        "Expiring Soon": 0
    },
    {
        "timestamp": "2021-10-31T16:29:18Z",
        "Not Covered": 135,
        "Active": 0,
        "Expiring Soon": 0
    }
]
4
  • Possible duplicate of stackoverflow.com/questions/68901819/… Commented Sep 1, 2021 at 13:33
  • @hacKaTun3s this is not my case Commented Sep 1, 2021 at 13:38
  • It is the exact same question, you can do this yourself mutating my answer. Commented Sep 1, 2021 at 13:40
  • How is what you're getting different from what is expected in that example? You really should pick an example where there is actually a difference... Commented Sep 1, 2021 at 14:04

2 Answers 2

3

You haven't explained how to get the values "Active" and "Expiring soon", but I'm sure something like that should help

const data = [
    {
        "timestamp": "2021-08-31T15:29:18Z",
        "result": [
            {
                "label": "Expiring Soon",
                "value": 57
            },
            {
                "label": "Not Covered",
                "value": 132
            },
            {
                "label": "Active",
                "value": 42
            }
        ]
    },
    {
        "timestamp": "2021-09-30T15:29:18Z",
        "result": [
            {
                "label": "Not Covered",
                "value": 135
            }
        ]
    },
    {
        "timestamp": "2021-10-31T16:29:18Z",
        "result": [
            {
                "label": "Not Covered",
                "value": 135
            },
            {
                "label": "Active",
                "value": 42
            }
        ]
    }
];

console.log(data.reduce((acc, {timestamp, result}) => {
    const datum = result.reduce((acc, {label, value}) => {
        acc[label] = value;
        return acc;
    }, {
        timestamp,
        'Not Covered': 0,
        Active: 0,
        'Expiring Soon': 0
    });
    return acc.concat(datum);
}, []));

Sign up to request clarification or add additional context in comments.

3 Comments

if we have an object in result array with active label set it ( like if we have { "label": "Active", "value": 135 }, set "Active":135, otherwise Active or Not Covered or Expiring Soon is absent --- set it as 0 value.
so the object in resulted array must include active,Not Covered, and Expiring Soon that set as 0 in the accamulator of reduce. but if we have any of these in the data that we reducing ---> then set in accordance with that data
@Olek okay, my answer has been changed
2

What about something like this? You can then just put your "Active" and "ExpringSoon" according to your business logic.

const array = data.map(item => {
  const results = {}
  item.result.forEach(({ label, value }) => results[label] = value )
  return {
    Active: 0,
    ExpiringSoon: 0,
    timestamp: item.timestamp,
    ...results
  }
})

Result

[
  {
    Active: 0,
    ExpiringSoon: 0,
    timestamp: '2021-08-31T15:29:18Z',
    'Not Covered': 132
  },
  {
    Active: 0,
    ExpiringSoon: 0,
    timestamp: '2021-09-30T15:29:18Z',
    'Not Covered': 135
  },
  {
    Active: 0,
    ExpiringSoon: 0,
    timestamp: '2021-10-31T16:29:18Z',
    'Not Covered': 135
  }
]

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.