Home > database >  How to Filter objects and arrays within Javascript Array
How to Filter objects and arrays within Javascript Array

Time:02-25

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:

  1. Filter out objects based on exposure type
  2. 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
  }, [])
}

  • Related