I have some static data I need to filter through based on a few parameters.
I am having some issues filtering deeper than the first value in the array. I reach the first part okay, but I'm not able to filter any deeper on the nested arrays. Here is what the data set looks like.
let data = [
{
exposureType: "Outdoor",
unixTime : [
1632513660, 1632515460, 1632517260, 1632519060, 1632520860, 1632522660,
1632524460, 1632526260, 1632528060, 1632529860, 1632531660, 1632533460,
1632535260, 1632537060, 1632538860, 1632540660, 1632542460, 1632544260,
1632546060, 1632547860, 1632549660, 1632551460, 1632553260, 1632555060,
1632556860, 1632558660, 1632560460, 1632562260, 1632564060, 1632565860,
1632567660, 1632569460, 1632571260, 1632573060, 1632574860, 1632576660,
1632578460, 1632580260, 1632582060, 1632583860, 1632585660, 1632587460,
1632589260, 1632591060, 1632592860, 1632594660, 1632596460, 1632598260,
1632600060, 1632601860, 1632603660, 1632605460, 1632607260, 1632609060,
],
rh : [
45.52, 46.08, 45.48, 44.91, 45.3, 45.82, 47.76, 48.45, 50.16, 51, 50.98,
52.8, 52.97, 53.91, 54.05, 54.27, 54.25, 54.27, 54.25, 54.29, 54.31,
54.18, 54.07, 54.09, 54.01, 53.91, 53.85, 54.18, 53.96, 54.07, 53.99,
53.39, 53.01, 53.53, 54.05, 54.9, 55.54, 56.2, 57.37, 56.91, 57.34
52.16, 51.15, 50.62, 50.33, 59.31, 67.55, 58.25, 62.4,
],
airTemp : [
22.5, 22.39, 22.35, 22.25, 22.23, 22.19, 22.12, 22.02, 21.97, 21.9,
21.88, 21.87, 21.8, 21.8, 21.7, 21.63, 21.53, 21.42, 21.3, 21.18, 21.06,
20.94, 20.79, 20.7, 20.57, 20.41, 20.24, 20.19, 20.13, 20.06, 20.06,
20.06, 20.02, 19.96, 19.93, 19.92, 19.91, 19.91, 19.93, 20, 20.08, 20.2,
20.32, 20.43, 20.57, 20.68, 20.81, 20.97, 21.08, 21.25, 21.39, 21.53,
21.64, 21.76, 21.78, 21.8, 21.85, 21.87, 21.9, 21.88, 21.87, 21.78,
21.76, 21.67, 21.6, 21.52, 21.43, 21.33, 21.23, 21.1, 21.05, 20.95
],
},
{
exposureType: "Laboratory",
unixTime: [
1632513660, 1632515460, 1632517260, 1632519060, 1632520860, 1632522660,
1632524460, 1632526260, 1632528060, 1632529860, 1632531660, 1632533460,
1632535260, 1632537060, 1632538860, 1632540660, 1632542460, 1632544260,
1632546060, 1632547860, 1632549660, 1632551460, 1632553260, 1632555060,
1632556860, 1632558660, 1632560460, 1632562260, 1632564060, 1632565860,
1632567660, 1632569460, 1632571260, 1632573060, 1632574860, 1632576660,
1632578460, 1632580260, 1632582060, 1632583860, 1632585660, 1632587460,
1632589260, 1632591060, 1632592860, 1632594660, 1632596460, 1632598260,
1632600060, 1632601860, 1632603660, 1632605460, 1632607260, 1632609060,
1632610860, 1632612660, 1632614460, 1632616260, 1632618060, 1632619860,
],
rh: [
45.52, 46.08, 45.48, 44.91, 45.3, 45.82, 47.76, 48.45, 50.16, 51, 50.98,
52.8, 52.97, 53.91, 54.05, 54.27, 54.25, 54.27, 54.25, 54.29, 54.31,
54.18, 54.07, 54.09, 54.01, 53.91, 53.85, 54.18, 53.96, 54.07, 53.99,
53.39, 53.01, 53.53, 54.05, 54.9, 55.54, 56.2, 57.37, 56.91, 57.34,
57.33, 56.26, 55.45, 54.81, 54.42, 53.81, 53.75, 53.48, 53.44, 53.75,
53.73, 53.57, 52.99, 53.93, 54.14, 54.71, 54.94, 55.8, 56.24, 55.38,
56.65, 55.79, 55.21, 55.02, 54.51, 54.18, 53.92, 53.75, 53.58, 53.56,
53.41, 53.63, 53.63, 53.48, 53.89, 53.98, 53.87, 53.59, 53.09, 53.03,
],
airTemp: [
22.5, 22.39, 22.35, 22.25, 22.23, 22.19, 22.12, 22.02, 21.97, 21.9,
21.88, 21.87, 21.8, 21.8, 21.7, 21.63, 21.53, 21.42, 21.3, 21.18, 21.06,
20.94, 20.79, 20.7, 20.57, 20.41, 20.24, 20.19, 20.13, 20.06, 20.06,
20.06, 20.02, 19.96, 19.93, 19.92, 19.91, 19.91, 19.93, 20, 20.08, 20.2,
20.32, 20.43, 20.57, 20.68, 20.81, 20.97, 21.08, 21.25, 21.39, 21.53,
21.64, 21.76, 21.78, 21.8, 21.85, 21.87, 21.9, 21.88, 21.87, 21.78,
],
},
];
I pass in four parameters that look like this.
sensorData("Outdoor", "airTemp", 20, 22)
I then want to filter on the first elemement like this.
let filterdArray = data.filter((val) => val.exposureType === exposureType );
This part seems to work. It will bring back the object labeled "Outdoor" in this instance. However, nothing past this point works.
I then aim to find the "airTemp" array and filter on it with min and max values. The 20 and 22 parameter values. it doesn't work though. I still brings back all arrays and values in that object.
I've tried things like this.
let filterdArray = data.filter((val) => val.exposureType === exposureType && val.airTemp > min && val.airTemp < max);
filterdArray.map((element) => {
return {...element, SubElements: element.SubElements.filter((subElement) => subElement.airTemp)}
})
Neither of which work.
I'm new to filtering in Javascript, so I'm not sure the best way to do this. Is there a way to accomplish what I've laid out ?
Grateful for your help.
CodePudding user response:
The Function
function filter_sensor_data_for_within_range(sensorData, exposureType, filterFor, minValue, maxValue) {
return filter_range(read_exposure_for(read_exposure_type(sensorData)));
function read_exposure_type(sensorData) {
if (sensorData && sensorData.length) {
return sensorData.find(dataEntry => dataEntry.exposureType === exposureType) || {};
}
return {};
}
function read_exposure_for(exposureData) {
return { exposureType: exposureData.exposureType, [filterFor]: exposureData[filterFor] || [] };
}
function filter_range(exposureDataProperty) {
return { exposureType: exposureDataProperty.exposureType, [filterFor]: exposureDataProperty[filterFor].filter((temp) => temp >= minValue && temp <= maxValue) };
}
}
Illustration
function filter_sensor_data_for_within_range(sensorData, exposureType, filterFor, minValue, maxValue) {
return filter_range(read_exposure_for(read_exposure_type(sensorData)));
function read_exposure_type(sensorData) {
if (sensorData && sensorData.length) {
return sensorData.find(dataEntry => dataEntry.exposureType === exposureType) || {};
}
return {};
}
function read_exposure_for(exposureData) {
return {
exposureType: exposureData.exposureType,
[filterFor]: exposureData[filterFor] || []
};
}
function filter_range(exposureDataProperty) {
return {
exposureType: exposureDataProperty.exposureType,
[filterFor]: exposureDataProperty[filterFor].filter((temp) => temp >= minValue && temp <= maxValue)
};
}
}
const data = [{
exposureType: "Outdoor",
unixTime: [
1632513660, 1632515460, 1632517260, 1632519060, 1632520860, 1632522660,
1632524460, 1632526260, 1632528060, 1632529860, 1632531660, 1632533460,
1632535260, 1632537060, 1632538860, 1632540660, 1632542460, 1632544260,
1632546060, 1632547860, 1632549660, 1632551460, 1632553260, 1632555060,
1632556860, 1632558660, 1632560460, 1632562260, 1632564060, 1632565860,
1632567660, 1632569460, 1632571260, 1632573060, 1632574860, 1632576660,
1632578460, 1632580260, 1632582060, 1632583860, 1632585660, 1632587460,
1632589260, 1632591060, 1632592860, 1632594660, 1632596460, 1632598260,
1632600060, 1632601860, 1632603660, 1632605460, 1632607260, 1632609060,
],
rh: [
45.52, 46.08, 45.48, 44.91, 45.3, 45.82, 47.76, 48.45, 50.16, 51, 50.98,
52.8, 52.97, 53.91, 54.05, 54.27, 54.25, 54.27, 54.25, 54.29, 54.31,
54.18, 54.07, 54.09, 54.01, 53.91, 53.85, 54.18, 53.96, 54.07, 53.99,
53.39, 53.01, 53.53, 54.05, 54.9, 55.54, 56.2, 57.37, 56.91, 57.34,
52.16, 51.15, 50.62, 50.33, 59.31, 67.55, 58.25, 62.4,
],
airTemp: [
22.5, 22.39, 22.35, 22.25, 22.23, 22.19, 22.12, 22.02, 21.97, 21.9,
21.88, 21.87, 21.8, 21.8, 21.7, 21.63, 21.53, 21.42, 21.3, 21.18, 21.06,
20.94, 20.79, 20.7, 20.57, 20.41, 20.24, 20.19, 20.13, 20.06, 20.06,
20.06, 20.02, 19.96, 19.93, 19.92, 19.91, 19.91, 19.93, 20, 20.08, 20.2,
20.32, 20.43, 20.57, 20.68, 20.81, 20.97, 21.08, 21.25, 21.39, 21.53,
21.64, 21.76, 21.78, 21.8, 21.85, 21.87, 21.9, 21.88, 21.87, 21.78,
21.76, 21.67, 21.6, 21.52, 21.43, 21.33, 21.23, 21.1, 21.05, 20.95
],
},
{
exposureType: "Laboratory",
unixTime: [
1632513660, 1632515460, 1632517260, 1632519060, 1632520860, 1632522660,
1632524460, 1632526260, 1632528060, 1632529860, 1632531660, 1632533460,
1632535260, 1632537060, 1632538860, 1632540660, 1632542460, 1632544260,
1632546060, 1632547860, 1632549660, 1632551460, 1632553260, 1632555060,
1632556860, 1632558660, 1632560460, 1632562260, 1632564060, 1632565860,
1632567660, 1632569460, 1632571260, 1632573060, 1632574860, 1632576660,
1632578460, 1632580260, 1632582060, 1632583860, 1632585660, 1632587460,
1632589260, 1632591060, 1632592860, 1632594660, 1632596460, 1632598260,
1632600060, 1632601860, 1632603660, 1632605460, 1632607260, 1632609060,
1632610860, 1632612660, 1632614460, 1632616260, 1632618060, 1632619860,
],
rh: [
45.52, 46.08, 45.48, 44.91, 45.3, 45.82, 47.76, 48.45, 50.16, 51, 50.98,
52.8, 52.97, 53.91, 54.05, 54.27, 54.25, 54.27, 54.25, 54.29, 54.31,
54.18, 54.07, 54.09, 54.01, 53.91, 53.85, 54.18, 53.96, 54.07, 53.99,
53.39, 53.01, 53.53, 54.05, 54.9, 55.54, 56.2, 57.37, 56.91, 57.34,
57.33, 56.26, 55.45, 54.81, 54.42, 53.81, 53.75, 53.48, 53.44, 53.75,
53.73, 53.57, 52.99, 53.93, 54.14, 54.71, 54.94, 55.8, 56.24, 55.38,
56.65, 55.79, 55.21, 55.02, 54.51, 54.18, 53.92, 53.75, 53.58, 53.56,
53.41, 53.63, 53.63, 53.48, 53.89, 53.98, 53.87, 53.59, 53.09, 53.03,
],
airTemp: [
22.5, 22.39, 22.35, 22.25, 22.23, 22.19, 22.12, 22.02, 21.97, 21.9,
21.88, 21.87, 21.8, 21.8, 21.7, 21.63, 21.53, 21.42, 21.3, 21.18, 21.06,
20.94, 20.79, 20.7, 20.57, 20.41, 20.24, 20.19, 20.13, 20.06, 20.06,
20.06, 20.02, 19.96, 19.93, 19.92, 19.91, 19.91, 19.93, 20, 20.08, 20.2,
20.32, 20.43, 20.57, 20.68, 20.81, 20.97, 21.08, 21.25, 21.39, 21.53,
21.64, 21.76, 21.78, 21.8, 21.85, 21.87, 21.9, 21.88, 21.87, 21.78,
],
},
];
console.log(filter_sensor_data_for_within_range(data, "Outdoor", "airTemp", 20, 22));
WYSIWYG
=> WHAT YOU SHOW IS WHAT YOU GET
CodePudding user response:
First filter, then map and filter the inner property values through the map.
const sensorData = (exposureType, property, min, max) => {
return data.filter((val) => val.exposureType === exposureType).map(v => {
if (v.hasOwnProperty(property)) v[property] = v[property].filter(f => f >= min && f <= max);
return v
})
}
sensorData("Outdoor", "airTemp", 20, 22)
let data = [{
exposureType: "Outdoor",
unixTime: [
1632513660, 1632515460, 1632517260, 1632519060, 1632520860, 1632522660,
1632524460, 1632526260, 1632528060, 1632529860, 1632531660, 1632533460,
1632535260, 1632537060, 1632538860, 1632540660, 1632542460, 1632544260,
1632546060, 1632547860, 1632549660, 1632551460, 1632553260, 1632555060,
1632556860, 1632558660, 1632560460, 1632562260, 1632564060, 1632565860,
1632567660, 1632569460, 1632571260, 1632573060, 1632574860, 1632576660,
1632578460, 1632580260, 1632582060, 1632583860, 1632585660, 1632587460,
1632589260, 1632591060, 1632592860, 1632594660, 1632596460, 1632598260,
1632600060, 1632601860, 1632603660, 1632605460, 1632607260, 1632609060
],
rh: [
45.52, 46.08, 45.48, 44.91, 45.3, 45.82, 47.76, 48.45, 50.16, 51, 50.98,
52.8, 52.97, 53.91, 54.05, 54.27, 54.25, 54.27, 54.25, 54.29, 54.31,
54.18, 54.07, 54.09, 54.01, 53.91, 53.85, 54.18, 53.96, 54.07, 53.99,
53.39, 53.01, 53.53, 54.05, 54.9, 55.54, 56.2, 57.37, 56.91, 57.34,
52.16, 51.15, 50.62, 50.33, 59.31, 67.55, 58.25, 62.4
],
airTemp: [
22.5, 22.39, 22.35, 22.25, 22.23, 22.19, 22.12, 22.02, 21.97, 21.9,
21.88, 21.87, 21.8, 21.8, 21.7, 21.63, 21.53, 21.42, 21.3, 21.18, 21.06,
20.94, 20.79, 20.7, 20.57, 20.41, 20.24, 20.19, 20.13, 20.06, 20.06,
20.06, 20.02, 19.96, 19.93, 19.92, 19.91, 19.91, 19.93, 20, 20.08, 20.2,
20.32, 20.43, 20.57, 20.68, 20.81, 20.97, 21.08, 21.25, 21.39, 21.53,
21.64, 21.76, 21.78, 21.8, 21.85, 21.87, 21.9, 21.88, 21.87, 21.78,
21.76, 21.67, 21.6, 21.52, 21.43, 21.33, 21.23, 21.1, 21.05, 20.95
],
},
{
exposureType: "Laboratory",
unixTime: [
1632513660, 1632515460, 1632517260, 1632519060, 1632520860, 1632522660,
1632524460, 1632526260, 1632528060, 1632529860, 1632531660, 1632533460,
1632535260, 1632537060, 1632538860, 1632540660, 1632542460, 1632544260,
1632546060, 1632547860, 1632549660, 1632551460, 1632553260, 1632555060,
1632556860, 1632558660, 1632560460, 1632562260, 1632564060, 1632565860,
1632567660, 1632569460, 1632571260, 1632573060, 1632574860, 1632576660,
1632578460, 1632580260, 1632582060, 1632583860, 1632585660, 1632587460,
1632589260, 1632591060, 1632592860, 1632594660, 1632596460, 1632598260,
1632600060, 1632601860, 1632603660, 1632605460, 1632607260, 1632609060,
1632610860, 1632612660, 1632614460, 1632616260, 1632618060, 1632619860
],
rh: [
45.52, 46.08, 45.48, 44.91, 45.3, 45.82, 47.76, 48.45, 50.16, 51, 50.98,
52.8, 52.97, 53.91, 54.05, 54.27, 54.25, 54.27, 54.25, 54.29, 54.31,
54.18, 54.07, 54.09, 54.01, 53.91, 53.85, 54.18, 53.96, 54.07, 53.99,
53.39, 53.01, 53.53, 54.05, 54.9, 55.54, 56.2, 57.37, 56.91, 57.34,
57.33, 56.26, 55.45, 54.81, 54.42, 53.81, 53.75, 53.48, 53.44, 53.75,
53.73, 53.57, 52.99, 53.93, 54.14, 54.71, 54.94, 55.8, 56.24, 55.38,
56.65, 55.79, 55.21, 55.02, 54.51, 54.18, 53.92, 53.75, 53.58, 53.56,
53.41, 53.63, 53.63, 53.48, 53.89, 53.98, 53.87, 53.59, 53.09, 53.03
],
airTemp: [
22.5, 22.39, 22.35, 22.25, 22.23, 22.19, 22.12, 22.02, 21.97, 21.9,
21.88, 21.87, 21.8, 21.8, 21.7, 21.63, 21.53, 21.42, 21.3, 21.18, 21.06,
20.94, 20.79, 20.7, 20.57, 20.41, 20.24, 20.19, 20.13, 20.06, 20.06,
20.06, 20.02, 19.96, 19.93, 19.92, 19.91, 19.91, 19.93, 20, 20.08, 20.2,
20.32, 20.43, 20.57, 20.68, 20.81, 20.97, 21.08, 21.25, 21.39, 21.53,
21.64, 21.76, 21.78, 21.8, 21.85, 21.87, 21.9, 21.88, 21.87, 21.78
],
},
];
const sensorData = (exposureType, property, min, max) => {
return data.filter((val) => val.exposureType === exposureType).map(v => {
if (v.hasOwnProperty(property)) v[property] = v[property].filter(f => f >= min && f <= max);
return v
})
}
console.log(sensorData("Outdoor", "airTemp", 20, 22))
CodePudding user response:
Issue with your approach:
val.exposureType === exposureType && val.airTemp > min && val.airTemp < max
This is an expression in filter and will be evaluated as false as val.airTemp
is an array. So you are comparing number with an array.
Solution:
You will have to imploy 2 step process:
- Filter out objects based on exposure type
- Loop on filtered objects and filter out
airTemp
- For this, you will have to use
.map
as you need a mutated value for all filtered objects. - Filter
airTemp
and save it in a variable - Use this value to override property in object and return this object
Example
function sensorData(exposureType, property, minVal, maxVal) {
const result = data
.filter((item) => item.exposureType === exposureType)
.map((item) => {
const value = item[property] &&
item[property].filter((val) => val >= minVal && val < maxVal)
return { ...item,
[property]: value
}
})
return result
}
Or if you want to do it in 1 loop:
function sensorData(exposureType, property, minVal, maxVal) {
return data.reduce((acc, item) => {
if (item.exposureType === exposureType) {
const filterVal = item[property] &&
item[property].filter((val) => minVal <= val && val < maxVal)
acc.push({
...item,
[property]: filterVal
})
}
return acc
}, [])
}