user1122
user1122

Reputation: 57

How to get a new array from an array with nested objects?

I have the below array:

 var data = [
   { "id":"id1", "key":"2020-07-15T06:32:44.08Z", "value":["E19","on"] },
   { "id":"id2", "key":"2020-07-15T06:32:44.08Z", "value":["E20","on"] },
   { "id":"id3", "key":"2020-07-15T06:32:44.08Z", "value":["E21","off"] },
   { "id":"id1", "key":"2020-07-15T06:33:44.08Z", "value":["E19","on"] },
   { "id":"id4", "key":"2020-07-15T06:34:44.08Z", "value":["E19","faulty"] },
   { "id":"id5", "key":"2020-07-15T06:35:44.08Z", "value":["E19","on"] }
  ];

I want this data to be converted to the below form to be used on Google charts:

var expectedData = [
    ["time","on","off","faulty"],
    ["06:32:44",2,1,0],
    ["06:33:44",2,1,0],  //here the count is same because E19 is only records for this time which is 
                      //already marked as 'on' in the before time stamp. Hence no change is required.

    ["06:34:44",1,1,1], //E19 has been changed to 'faulty', hence 'on' is reduced by 1 and 'faulty' 
                        //increased by 1
    ["06:35:44",2,1,0]  //E19 is changed back to 'on' hence 'on' is increased by 1 and 'faulty' 
                        //reduced by 1
 ];

Can someone please help me with javascript code to sort this data to be used in my React Google charts?

I have written the below code so far:

    const data = [
        { "id":"id1", "key":"2020-07-15T06:32:44.08Z", "value":["GigabyteEthernet4/0/19","on"] },
        { "id":"id2", "key":"2020-07-15T06:32:44.08Z", "value":["GigabyteEthernet4/0/20","on"] },
        { "id":"id3", "key":"2020-07-15T06:32:44.08Z", "value":["GigabyteEthernet4/0/21","off"] },
        { "id":"id1", "key":"2020-07-15T06:33:44.08Z", "value":["GigabyteEthernet4/0/19","on"] },
        { "id":"id4", "key":"2020-07-15T06:34:44.08Z", "value":["GigabyteEthernet4/0/19","faulty"] },
        { "id":"id5", "key":"2020-07-15T06:35:44.08Z", "value":["GigabyteEthernet4/0/19","on"] }
    ];

    // var poeObj = new Object();
    let t;
    var newArray= [];
    var newData = data.map((item,el)=>{
        t= new Date(item.key);
        var poeObj = Object.assign({},el)
        poeObj.time= t.toLocaleTimeString();
        poeObj.intfName= item.value[0];
        poeObj.state= item.value[1];
        if(poeObj.intfName)
        console.log(poeObj);
        return poeObj;
    })
    console.log(newData)

    var newData1 = [
        {time: "12:02:44 PM", intfName: "GigabyteEthernet4/0/19", state: "on"},
        {time: "12:02:44 PM", intfName: "GigabyteEthernet4/0/20", state: "on"},
        {time: "12:02:44 PM", intfName: "GigabyteEthernet4/0/21", state: "off"},
        {time: "12:03:44 PM", intfName: "GigabyteEthernet4/0/19", state: "on"},
        {time: "12:04:44 PM", intfName: "GigabyteEthernet4/0/19", state: "faulty"},
        {time: "12:05:44 PM", intfName: "GigabyteEthernet4/0/19", state: "on"}
    ]

    var uniqueData = newData1.reduce((arr,item)=>{
        var newArr = [];
        newArr.push(item.time, item.intfName, item.state);
        console.log(newArr)
        arr.push(newArr)
        return arr;
    },[])
    console.log(uniqueData)
   //uniqueData= [
        ["12:02:44 PM", "GigabyteEthernet4/0/19", "on"],
        ["12:02:44 PM", "GigabyteEthernet4/0/20", "on"],
        ["12:02:44 PM", "GigabyteEthernet4/0/21", "off"],
        ["12:03:44 PM", "GigabyteEthernet4/0/19", "on"],
        ["12:04:44 PM", "GigabyteEthernet4/0/19", "faulty"],
        ["12:05:44 PM", "GigabyteEthernet4/0/19", "on"]
    ];

After all these code, I have got the formatted array as the above 'uniqueData'. But not sure if this is the efficient way. Although, I idn't reach my final expected output which is 'expectedData' mentioned in the begining. Can some one please advise me on this?

Upvotes: 0

Views: 78

Answers (1)

Rene Padillo
Rene Padillo

Reputation: 2358

You can transform the content of your item in an array by using Array map function.

If I have the following:

var data = [
   { "id":"1", "title":"Lorem ipsum" },
   { "id":"2", "title":"Test title" },
   { "id":"3", "title":"another title" },
];

I can do:

// .map will traverse each item and we pass a function on how we want to deal with new item structure
data.map((item) => {
   // I will convert individual item to this format: Array[id, title]
   return [item.id, item.title]
})

This will return

[
    [1, "Lorem ipsum"],
    [2, "Test title"],
    [3, "another title"],
]

In your question you have a different item structure in your array ["time","on","off","faulty"]

by getting the output from .map you just append using .splice ["time","on","off","faulty"] from your .map result.

// This will append ["time","on","off","faulty"] in the first index of array
result.splice(0, 0, ["time","on","off","faulty"])

Using reduce is also possible

I can do:

// Reduce also works by merging items, it can take two parameters (function, initial value)
data.reduce((accumulated, currentItem) => {
   accumulated.push([currentItem.id, currentItem.title])
}, [["time","on","off","faulty"]])

This will have similar output with .map, the difference is you can put ahead the ["time","on","off","faulty"] in your new array without doing splice.

Upvotes: 3

Related Questions