Guidelines for Sorting Objects and Arrays in a JavaScript Array

I have a set of data that needs to be filtered based on specific parameters.

While I can successfully filter through the initial value in the array, I am struggling to filter deeper into nested arrays. The dataset is structured as follows:

let data = [
    {
      exposureType: "Outdoor",
      unixTime : [
        // unixTime values
      ],
      rh : [
        // Relative humidity values
      ],
      airTemp : [
        // Air temperature values
      ],
    },
    {
      exposureType: "Laboratory",
      unixTime: [
        // unixTime values for laboratory
      ],
      rh: [
        // Relative humidity values for laboratory
      ],
      airTemp: [
         // Air temperature values for laboratory
      ],
    },
  ];

When I pass in four parameters like this:

sensorData("Outdoor", "airTemp", 20, 22)

I want to filter based on the first element using code like this:

  let filteredArray = data.filter((val) => val.exposureType === exposureType );

Although the above code works to retrieve the object labeled "Outdoor," everything beyond this point does not work.

My goal is to access the "airTemp" array and apply filtering based on minimum and maximum values (in this case, 20 and 22). However, my attempts so far haven't been successful as it continues to return all arrays and values within that object.

I have experimented with different approaches such as:

let filteredArray = data.filter((val) => val.exposureType === exposureType && val.airTemp > min && val.airTemp < max);



filteredArray.map((element) => {
    return {...element, SubElements: element.SubElements.filter((subElement) => subElement.airTemp)}
  })

Unfortunately, neither of these methods has yielded the desired results.

Being new to JavaScript filtering, I am uncertain about the most effective way to achieve what I've outlined here. Can you suggest a method to accomplish this filtering task?

Your assistance is greatly appreciated.

Answer №1

The Process

function validate_temperature_data_for_exposure(sensorData, typeOfExposure, filterBy, minTemp, maxTemp) {
    return filtered_temperature_range(extract_exposure_data_for_type(filter_exposure_type(sensorData)));
    
    function filter_exposure_type(sensorData) {
        if (sensorData && sensorData.length) {
            return sensorData.find(entry => entry.typeOfExposure === typeOfExposure) || {};
        }
        return {};
    }

    function extract_exposure_data_for_type(exposureData) {
        return { exposureType: exposureData.typeOfExposure, [filterBy]: exposureData[filterBy] || [] };
    }

    function filtered_temperature_range(exposureDataProperty) {
        return { exposureType: exposureDataProperty.exposureType, [filterBy]: exposureDataProperty[filterBy].filter((temp) => temp >= minTemp && temp <= maxTemp) };
    }
}

Visual Representation

function validate_temperature_data_for_exposure(sensorData, typeOfExposure, filterBy, minTemp, maxTemp) {
  return filtered_temperature_range(extract_exposure_data_for_type(filter_exposure_type(sensorData)));

  function filter_exposure_type(sensorData) {
    if (sensorData && sensorData.length) {
      return sensorData.find(entry => entry.typeOfExposure === typeOfExposure) || {};
    }
    return {};
  }

  function extract_exposure_data_for_type(exposureData) {
    return {
      exposureType: exposureData.typeOfExposure,
      [filterBy]: exposureData[filterBy] || []
    };
  }

  function filtered_temperature_range(exposureDataProperty) {
    return {
      exposureType: exposureDataProperty.exposureType,
      [filterBy]: exposureDataProperty[filterBy].filter((temp) => temp >= minTemp && temp <= maxTemp)
    };
  }
}
const temperatureData = [{
    typeOfExposure: "Outdoor",
    unixTime: [
      1632513660, 1632515460, 1632517260, 1632519060, 1632520860, 1632522660,
      1632524460, 1632526260, 1632528060, 1632529860
    ],
    rh: [45.52, 46.08, 45.48, 44.91, 45.3],
    airTemp: [22.5, 22.39, 22.35, 22.25, 22.23]
  },
  {
    typeOfExposure: "Laboratory",
    unixTime: [
      1632513660, 1632515460, 1632517260, 1632519060, 1632520860
    ],
    rh: [45.52, 46.08, 45.48, 44.91, 45.3],
    airTemp: [22.5, 22.39, 22.35, 22.25, 22.23]
  }
];
console.log(validate_temperature_data_for_exposure(temperatureData, "Outdoor", "airTemp", 20, 22));


WYSIWYG => WHAT YOU SHOW IS WHAT YOU GET

Answer №2

Implement the sensor data function to filter and map property values based on specified conditions.

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 = [{   << Simplified for brevity >>
    exposureType: "Outdoor",
    unixTime: [1632513660, 1632515460, ...],
    rh: [45.52, 46.08, ...],
    airTemp: [22.5, 22.39, ...],
  },
  {
    exposureType: "Laboratory",
    unixTime: [1632513660, 1632515460, ...],
    rh: [45.52, 46.08, ...],
    airTemp: [22.5, 22.39, ...],
  },
];

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))

Answer №3

Problem with the current approach:

val.exposureType === exposureType && val.airTemp > min && val.airTemp < max

The issue here is that in the filter expression, val.airTemp is an array, so you are comparing a number with an array which will result in false evaluation.

Solution to fix this problem:

You need to follow a 2-step process:

  1. Filter out objects based on exposure type
  2. Iterate through filtered objects and filter out airTemp
  • To achieve this, you should use .map as it allows mutation of values for all filtered objects.
  • Filter out airTemp values and store them in a variable
  • Use these filtered values to update the property in the object and return the modified object

Example Provided Here

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
}

Alternatively, if you prefer doing it in a single 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
  }, [])
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is there a way to conduct a Mongoose query that excludes or ignores specific strings?

I'm struggling to find a concise title, so please suggest ways to make it clearer. Now, onto my question - I need to query phone numbers in my database, but they are stored in two different formats: with dashes and without. For example: {phone: ' ...

Using useCallback with an arrow function as a prop argument

I'm having trouble understanding the code snippet below <Signup onClick={() => {}} /> Upon inspecting the Signup component, I noticed the implementation of useCallback as follows const Signup = ({onClick}) => { const handleClick = us ...

Analyzing the stock market data on Yahoo Finance

import urllib.request, urllib.error m = 0 web ='x' # This script fetches the stock value for "United States Steel Corp." t =str(web) try: f = urllib.request.urlopen('http://finance.yahoo.com/q?s='+ t +'') except ValueEr ...

Guide to efficiently populating a self-referential Mongoose model

My goal is to populate data across multiple levels using the fields from an Article model: comments: [ { type: Schema.Types.ObjectId, ref: "Comment" } ] and also from ...

AJAX seems to be struggling to recognize JSON data as JSON format

I am facing an issue with my AJAX call where the data received from the server is not being treated as JSON, despite setting the datatype to json: function RetrieveMateriasFromServer(callback){ var status_aux; //HTTP request for data from the given UR ...

Exploring object-level "this" behavior in jQuery

If I were to implement the following code snippet: const CustomObject = function() { this.showAlert = function() { alert("Hello World!"); } } CustomObject.prototype.bindToElement = function(element) { const self = this; $(element).bind(' ...

Tips for using jQuery to send a file to the connect-busboy module in nodejs

Successfully sending a file to connect-busboy can be achieved by utilizing an HTML form's action attribute in the following manner: <form ref='uploadForm' method="post" action="http://localhost:3000/fileupload" enctype="multipart/form-da ...

What is the best way to alter the color of faces in three.js?

I'm currently working with a sample script that involves flying bird objects. However, I am struggling to figure out how to change the color of the birds. I attempted to modify the color on the line where the birds are instantiated: bird = birds[i] ...

Aggregation cannot utilize $elemMatch

I'm facing an issue where I can't use $elemMatch within the aggregate function. Below is the code snippet that I'm struggling with, and I'm looking for an alternative approach to achieve the same result. My goal is to match and retrieve ...

Mastering the concept of promise chaining through this straightforward example

I'm struggling to implement a logic where I need to compare the user's password to a given password and handle different scenarios based on the comparison result. Here's what I need to achieve: If the user doesn't exist, return undefi ...

The moduleId in "Ng2SliderComponent" must be a valid string

My angularcli.json configuration looks like this: "scripts": [ "../node_modules/ng2-slider-component/ng2-slider.component.js", "../node_modules/ng2-slideable-directive/slideable.directive.js", "../node_modules/ng2-styled-directiv ...

Steps for accessing individual elements in an array in Perl

my@arr=qw(Larrywall); I have an array called @arr which contains the name "Larrywall". How can I access only the letter Y from this array? Any helpful suggestions would be greatly appreciated. ...

Struggling to properly line up the baselines of navigation list items that are styled as circular elements using CSS

I have transformed my navigation menu into a series of CSS circles with text inside. The issue I am facing is that the text spills out unevenly based on the amount of content in each circle. To address this, I used a JavaScript solution to center-align the ...

axios encountering a 400 bad request error during the get request

I've hit a roadblock for some time now while trying to make a call to my API to fetch data using the GET method. I keep getting a 400 bad request error in Postman, even though I am able to successfully retrieve the data with a status code of 200. I ha ...

Creating a layered structure in React using custom components within the Material-UI tree

As someone new to the world of React and Javascript, I am struggling to understand why my code is not behaving as expected. I am attempting to create a tree structure using custom components as branches. However, when I run the code, the child objects do n ...

The behavior of Android webview varies when executing JavaScript code

I am currently involved in a project that involves reading user input via voice and displaying it on a website. I am able to read all input IDs on the site using Jsoup. WebView webView = (WebView) findViewById(R.id.webview); webView.getSetting ...

Caption image on hover

Is it possible to make an image overlap text on a horizontal menu bar when hovering with the mouse? I am designing a horror website and would like a bloody handprint to appear over the links in the menu bar when they are hovered over. I know this can be do ...

Using `ng-model` within an Angular directive

Looking to achieve bi-directional binding in an Angular directive Here is my current approach: angular.module('myapp',[]),directive('mydirective', function() { var directive = {}; directive.restrict = 'E'; directi ...

What's the best way to manage endless routing options in express.js?

After reviewing the topic of handling routes in Express.js on Stack Overflow, I came across the following example : var express = require("express"); var app = express(); app.get("/", function(request, response) { response.send(&quo ...

Changing the i18n locale in the URL and navigating through nested routes

Seeking assistance to navigate through the complexities of Vue Router configurations! I've dedicated several days to integrating various resources, but have yet to achieve successful internalization implementation with URL routes in my unique setup. ...