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
- You have a wrong variable name in the
state.sensorData[i]?.Events
inside theconcat
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
);
- 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