Home > Back-end >  Unable to concatenate two arrays inside two arrays without duplicate
Unable to concatenate two arrays inside two arrays without duplicate

Time:06-29

So I have two arrays of data data.SensorData and state.SensorData they contain similar sensors information, however data.SensorData always get new Events data.SensorData[i].Events and I would like to concatenate the two Events without having duplicate events

here is the code I wrote

      console.log(state.sensorData[0].Events.length);//50
      for (let i = 1; i < data.SensorData.length; i  ) {
        console.log("<...");
        data.SensorData[i].Events = data.SensorData[i]?.Events.concat(
          state.sensorData[i]?.Events
        );
      }
      //should be 100 events but it stays 50
      console.log(state.sensorData[0].Events.length);//50 

Basically, they are not concatenating.

The JSON looks like this

[
{SensorID: 1, BatteryPct: 100, LastActiveTime: 1656461958000, LastStatus: 'ONLINE', Events: Array(50)}
{SensorID: 2, BatteryPct: 80, LastActiveTime: 1656461593000, LastStatus: 'ONLINE', Events: Array(50)}
{SensorID: 3, BatteryPct: 80, LastActiveTime: 1656462563000, LastStatus: 'ONLINE', Events: Array(50)}
{SensorID: 4, BatteryPct: 80, LastActiveTime: 1656462563000, LastStatus: 'ONLINE', Events: Array(50)}
{SensorID: 5, BatteryPct: 42, LastActiveTime: 1656424819000, LastStatus: 'ONLINE', Events: Array(50)}
{SensorID: 6, BatteryPct: null, LastActiveTime: 1656318675000, LastStatus: 'ONLINE', Events: Array(50)}
{SensorID: 7, BatteryPct: null, LastActiveTime: 1656253855000, LastStatus: 'ONLINE', Events: Array(50)}
{SensorID: 8, BatteryPct: 80, LastActiveTime: 1656447026000, LastStatus: 'OFFLINE', Events: Array(50)}
]

CodePudding user response:

Corrections

  1. You have a wrong variable name in the state.sensorData[i]?.Events inside the concat method
data.SensorData[i].Events = data.SensorData[i]?.Events.concat(
          state.sensorData[i]?.Events
        );

It should be capital 'S' in state.SensorData[i]?.Events

data.SensorData[i].Events = data.SensorData[i]?.Events.concat(
          state.SensorData[i]?.Events
        );
  1. You are also starting the array from the first index rather than zero index, while printing the zero index element
for (let i = 1...

should be

for (let i = 0...

Solution

The concat method does not remove duplicates, as per the documentation

The concat() method is used to merge two or more arrays. This method does not change the existing arrays, but instead returns a new array.

You need to remove them your self. To do so you can use a function like

function removeDuplicatesFromArray(array) {
    var a = array.concat();
    for(var i=0; i<a.length;   i) {
        for(var j=i 1; j<a.length;   j) {
            if(a[i] === a[j]) // Check here against whatever your unique value is
                a.splice(j--, 1);
        }
    }
    return a;
}

so your code would eventually become

console.log(state.sensorData[0].Events.length);//50
      for (let i = 0; i < data.SensorData.length; i  ) {
        console.log("<...");
        data.SensorData[i].Events = removeDuplicatesFromArray(data.SensorData[i]?.Events.concat(
          state.SensorData[i]?.Events
        ));
      }
      //should be 100 events but it stays 50
      console.log(state.sensorData[0].Events.length);//50 

Running Example

function removeDuplicatesFromArray(array) {
    var a = array.concat();
    for(var i=0; i<a.length;   i) {
        for(var j=i 1; j<a.length;   j) {
            if(a[i] === a[j]) // Check here against whatever your unique value is
                a.splice(j--, 1);
        }
    }
    return a;
}

var SensorData = [
{"SensorID": 1, "BatteryPct": 100, "LastActiveTime": 1656461958000, "LastStatus": "ONLINE", "Events": [1,2,3,4]},
{"SensorID": 1, "BatteryPct": 100, "LastActiveTime": 1656461958000, "LastStatus": "ONLINE", "Events": [1,2,3,4]}
];

var NewSensorData = [
{"SensorID": 1, "BatteryPct": 100, "LastActiveTime": 1656461958000, "LastStatus": "ONLINE", "Events": [1,2,3,4,5]},
{"SensorID": 1, "BatteryPct": 100, "LastActiveTime": 1656461958000, "LastStatus": "ONLINE", "Events": [1,2,3,4,7,8]}
];

console.log("Old Events Values");
SensorData.forEach((x) => console.log(x.Events));
for (let i = 0; i < SensorData.length; i  ) {
  SensorData[i].Events = removeDuplicatesFromArray(SensorData[i].Events.concat(
    NewSensorData[i].Events
  ));
}
console.log("New Events Values");
SensorData.forEach((x) => console.log(x.Events));

CodePudding user response:

Eagnir's answer is a good way to go about it coding your own duplicate filter function. You can also use javascript's built in hashset object to construct an set of unique values from your two arrays, then convert it back to an array.

For this solution, I've assumed that your state.sensorData will be a unique object because I'm not sure if you will always get a 1-to-1 match between your state and your data objects. You would then just modify the below code to nest another for-loop.

Running example (scroll to bottom to see solution):

let data = {
  SensorData: [
    {
      SensorID: 1,
      BatteryPct: 100,
      LastActiveTime: 1656461958000,
      LastStatus: 'ONLINE',
      Events: Array.from({ length: 50 }, () => Math.floor(Math.random() * 50)),
    },
    {
      SensorID: 2,
      BatteryPct: 80,
      LastActiveTime: 1656461593000,
      LastStatus: 'ONLINE',
      Events: Array.from({ length: 50 }, () => Math.floor(Math.random() * 50)),
    },
    {
      SensorID: 3,
      BatteryPct: 80,
      LastActiveTime: 1656462563000,
      LastStatus: 'ONLINE',
      Events: Array.from({ length: 50 }, () => Math.floor(Math.random() * 50)),
    },
    {
      SensorID: 4,
      BatteryPct: 80,
      LastActiveTime: 1656462563000,
      LastStatus: 'ONLINE',
      Events: Array.from({ length: 50 }, () => Math.floor(Math.random() * 50)),
    },
    {
      SensorID: 5,
      BatteryPct: 42,
      LastActiveTime: 1656424819000,
      LastStatus: 'ONLINE',
      Events: Array.from({ length: 50 }, () => Math.floor(Math.random() * 50)),
    },
    {
      SensorID: 6,
      BatteryPct: null,
      LastActiveTime: 1656318675000,
      LastStatus: 'ONLINE',
      Events: Array.from({ length: 50 }, () => Math.floor(Math.random() * 50)),
    },
    {
      SensorID: 7,
      BatteryPct: null,
      LastActiveTime: 1656253855000,
      LastStatus: 'ONLINE',
      Events: Array.from({ length: 50 }, () => Math.floor(Math.random() * 50)),
    },
    {
      SensorID: 8,
      BatteryPct: 80,
      LastActiveTime: 1656447026000,
      LastStatus: 'OFFLINE',
      Events: Array.from({ length: 50 }, () => Math.floor(Math.random() * 50)),
    },
  ],
};

const state = {
  sensorData: {
    Events: Array.from({ length: 50 }, () => Math.floor(Math.random() * 100)),
  },
};

console.log(data.SensorData[0].Events.length); //50
for (let i = 0; i < data.SensorData.length; i  ) {
  let hashSet = new Set();
  data.SensorData[i].Events.forEach((e) => hashSet.add(e));
  state.sensorData.Events.forEach((e) => hashSet.add(e));
  data.SensorData[i].Events = Array.from(hashSet);
}

//should be 100 events but it stays 50
console.log(data.SensorData[0].Events.length); //100

  • Related