简体   繁体   中英

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?

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.

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