1

I've got the following JSON:

var obj = 
{
  "workers": [
    {
      "TimeStamp": "2020-03-13T10:08",
      "Status": "status1",
      "Name": "one",
      "Number": 19.9
    },
    {
      "TimeStamp": "2019-07-19T06:01",
      "Status": "status2",
      "Name": "one",
      "Number": 9
    },
    {
      "TimeStamp": "2020-04-22T05:10",
      "Status": "status2",
      "Name": "one",
      "Number": 10.1
    },
    {
      "TimeStamp": "2019-07-21T23:53",
      "Status": "status2",
      "Name": "two",
      "Number": 16.3 
    },
    {
      "TimeStamp": "2019-11-21T05:14",
      "Status": "status1",
      "Name": "three",
      "Number": 122.54
    },
    ...
  ]
};

As you see there's just 2 different status possible: "status1" and "status2". Names should be filtered to be shown just once, but combine the two different status. The respective status should include the "TimeStamp" and "Number" in an array.

In the end it should look like this:

{
  "workers": [
    {
      "Name":"one",
      "status1": [
        {
          "TimeStamp":"2020-03-13T10:08",
          "Number": 19.9
        }
      ],
      "status2": [
        {
          "TimeStamp":"2019-07-19T06:01",
          "Number": 9
        },
        {
          "TimeStamp": "2020-04-22T05:10",
          "Number": 10.1
        },
      ]
    },
    {
      "Name":"two",
      "status1": [],
      "status2": [
        {
          "TimeStamp":"2019-07-21T23:53",
          "Number": 16.3
        }
      ]
    },
    {
      "Name":"three",
      "status1": [
        {
          "TimeStamp":"2019-11-21T05:14",
          "Number": 122.54
        }
      ],
      "status2": []
     }
  ]
}

I tried out the following so far:

var writeObj = { 'workers': [] };

for (var i = 0; i < obj.workers.length; i++) {
    if(!Object.values(writeObj.workers).includes(obj.workers[i].Name)) {

        writeObj['workers'].push({ Name: obj.workers[i].Name, 'status1': [], 'status2': [] });
        for (var j = 0; j < obj.workers.length; j++) {
            if (obj.workers[j].Name === obj.workers[i].Name && obj.workers[j].Status === 'status1') {
                writeObj['workers'][i]['status1'].push({ TimeStamp: obj.workers[j].TimeStamp, Number: obj.workers[j].Number });
            } else if (obj.workers[j].Name === obj.workers[i].Name && obj.workers[j].Status === 'status2') {
                writeObj['workers'][i]['status2'].push({ TimeStamp: obj.workers[j].TimeStamp, Number: obj.workers[j].Number });
            }
        }
    } 
}

I'm stuck and can't see the mistake... Thanks for any help!

1
  • What's the result you've seen so far with the code you have? Commented May 18, 2020 at 16:53

2 Answers 2

3

You can aggregate your data using array.reduce:

var obj = 
{
  "workers": [
    {
      "TimeStamp": "2020-03-13T10:08",
      "Status": "status1",
      "Name": "one",
      "Number": 19.9
    },
    {
      "TimeStamp": "2019-07-19T06:01",
      "Status": "status2",
      "Name": "one",
      "Number": 9
    },
    {
      "TimeStamp": "2020-04-22T05:10",
      "Status": "status2",
      "Name": "one",
      "Number": 10.1
    },
    {
      "TimeStamp": "2019-07-21T23:53",
      "Status": "status2",
      "Name": "two",
      "Number": 16.3 
    },
    {
      "TimeStamp": "2019-11-21T05:14",
      "Status": "status1",
      "Name": "three",
      "Number": 122.54
    }
  ]
};

let output = obj.workers.reduce((acc,cur) => {
    let {Name, Status, ...rest} = cur;
    let match = acc.find(x => x.Name === Name);
    if(!match){
       match = { Name: Name };
       acc.push(match);
    }
    if(!match[Status]){
       match[Status] = [];
    }
    match[Status].push(rest);
    return acc;
}, []);

console.log({workers: output});

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

Comments

0

You can use Array#reduce. Group by the Name key according to your format, then take the grouped values as the result. Time complexity is O(n).

var obj = { "workers": [ { "TimeStamp": "2020-03-13T10:08", "Status": "status1", "Name": "one", "Number": 19.9 }, { "TimeStamp": "2019-07-19T06:01", "Status": "status2", "Name": "one", "Number": 9 }, { "TimeStamp": "2020-04-22T05:10", "Status": "status2", "Name": "one", "Number": 10.1 }, { "TimeStamp": "2019-07-21T23:53", "Status": "status2", "Name": "two", "Number": 16.3 }, { "TimeStamp": "2019-11-21T05:14", "Status": "status1", "Name": "three", "Number": 122.54 }, ] };

const grouped = Object.values(obj.workers.reduce((a, e) => {
  if (!a[e.Name]) {
    a[e.Name] = {Name: e.Name, status1: [], status2: []};
  }
  
  a[e.Name][e.Status].push({TimeStamp: e.TimeStamp, Number: e.Number});
  return a;
}, {})); 

console.log(grouped);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.