Filtering an array of objects in real-time

var individuals = [
  { Skin: "Bronze", Place: ["South"] },
  { Skin: "Copper", Place: ["North", "South"] },
  { Skin: "Copper", Place: ["North"] }
];

var requirements = [
   { Field: "Skin", Values: ["Copper"] },
   { Field: "Place", Values: ["North", "South"] }
];

In this scenario, the skin field is a string type, and the place field is an array. There are various individuals listed, along with specified filter criteria. The goal is to display only those records where all selected values in the filter match with the data. This includes checking for an exact match based on all criteria provided (without any OR conditions).

Hence, the desired output will be:

{ Skin: "Copper", Place: ["North", "South"] }

If the filter criteria changes to:

var requirements = [
       { Field: "Skin", Values: ["Copper"] },
       { Field: "Place", Values: ["North"] }
    ];

The output would then include:

{ Skin: "Copper", Place: ["North", "South"] },
{ Skin: "Copper", Place: ["North"] }

It's essential that all specified filter values align with the records completely.

Answer №1

I decided to approach the issue by breaking it down into individual functions. While my solution may be more lengthy compared to yours, I believe it is easier to read and understand.

Most importantly, it does produce the desired outcome.

var people = [
  { Color: "Gold", Location: ["Down"] },
  { Color: "Silver", Location: ["Up", "Down"] },
  { Color: "Silver", Location: ["Up"] }
];

var conditions = [
   { Field: "Color", Values: ["Silver"] },
   { Field: "Location", Values: ["Up", "Down"] }
];

const compareArrays = (arr1, arr2) => {
  // A simple function for comparing arrays.
  if (arr1.length !== arr2.length) return false;
  arr1 = arr1.sort();
  arr2 = arr2.sort();
  for(let i=0; i < arr1.length; i++) {
    if (arr1[i] !== arr2[i]) return false;
  }
  return true;
};

let finalResult = people.filter(person => {
  // Ensuring all conditions are met.
  for (let condition of conditions) {
    if (condition.Field === 'Color') {
      if (person.Color !== condition.Values[0]) return false;
    }
    if (condition.Field === 'Location') {
      if (!compareArrays(person.Location, condition.Values)) return false;
    }
  }
  // If no mismatches were found, then we have a match!
  return true;
});
console.log(finalResult);

/*
{ Color: "Silver", Location: ["Down", "Up"] }
*/

Visit https://repl.it/@niels_bom/SparklingSolutionMicrobsd to see this code in action.

Answer №2

After making the third revision, it is now clear to me that you are looking to have an array as a subset of another.

var result = persons.filter(function (person) {
    return criteria.every(function (c) {
        var value = person[c.Field];
        if (typeof value === 'object') {
                return c.Values.length<=value.length && 
                c.Values.every(function(v,i){return value.includes(v) ;});
        }
        else
            return c.Values.indexOf(value) > -1;
    })
})

I have also made updates to your jsfiddle here: https://jsfiddle.net/gzL42dna/2/

Be sure to check out: How to compare arrays in JavaScript?

Answer №3

This solution is effective. The use of a Set significantly improves handling partial matches. Feel free to ask for clarification on the code if needed.

var items = [
  { Type: "Book", Genre: ["Adventure"] },
  { Type: "Movie", Genre: ["Comedy", "Drama"] },
  { Type: "Music", Genre: ["Rock"] }
];

var filters = [
   { Field: "Type", Values: ["Movie"] },
   { Field: "Genre", Values: ["Comedy", "Drama"] }
];

console.log(filterItems(items, filters));

function filterItems(items, filters) {
  let itemMatches = [...items]
  for (let i=0; i < filters.length; i++) {
    let {Field, Values} = filters[i]
    itemMatches = itemMatches.filter(obj => {
      if (Array.isArray(obj[Field])) {
        return checkMatches(obj[Field], Values)
      } else {
        return Values.includes(obj[Field])
      }
    })
  }
  return itemMatches
}

function checkMatches(arr1, criteria) {
  let criteriaSet = new Set(criteria)
  let itemsSet = new Set(arr1)
  for (let el of criteriaSet) {
    if (!itemsSet.has(el)) return false
  }
  return true
}

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

Filter an array of objects that include a nested array

Currently, I am attempting to implement a nested filter on an array of objects. The challenge lies in applying the filter within the object based on a key that contains another array of objects. Below is the snippet of code: const items = [ { name: &quo ...

What is the process for securing a photo to a canvas?

I have included <input type='file' id="image"> in my HTML code. How can I display the uploaded image on my canvas using p5.js? What is the best way to add an event listener to this action and transfer the uploaded file onto the ca ...

Facing a problem with the execution of the Lightence Ant Design React Template

As a beginner in reactJS, I am attempting to utilize lightence-ant-design. https://github.com/altence/lightence-ant-design-react-template/tree/main According to the instructions on GitHub, I followed the steps below: To ensure compatibility with the lates ...

Sort Array List by Boolean first, followed by Date in JavaScript/TypeScript

Introducing a new item dynamically to the list and organizing it by status followed by date. Here's the functional code: I need the list to display items with false status in descending order of date first, then true status items sorted by date when ...

Tips for managing onClick code when a user selects "open link in new tab" within a React js environment

How can I ensure that my tracking code runs when a user clicks a button in my React project, even if they open it in a new tab? Is there a solution for this in React JS? Here's a simple example: var Hello = React.createClass({ render: function( ...

How to retrieve the last non-empty element from an array in PHP?

I'm facing a problem with the PHP Array. I need to extract the last element from an array that is neither null nor blank. $string = '9580 County Road Clarence Center, New York 14032 TEL: 716-86 ...

Is there a way to adjust a 5-minute countdown interval timer by 1 minute in a react JS application?

I am in need of creating a 5-minute interval timer using react JS, with a 1-minute offset. The current timer I have functions like this: 1:00 => 1:05 => 1:10 => 1:15 => 1:20. However, I require it to be adjusted to display: 1:01 => 1:0 ...

Save the index of a Numpy array to a variable

Can someone advise me on how to pass an index slice as an argument to a function? def myfunction(some_object_for_array_creation, my_index=[1:5:2,::3]): my_array = create_array_from_object(some_object_for_array_creation) return my_array[my_index] ...

Organize Dates in React Table

I need help with sorting the Date column in my code. Currently, the sorting is being done alphabetically. Here is the JSON data and code snippet: JSON [ { "date": "Jun-2022" }, { "date": "Jul-2022" } ...

Navigating the process of debugging TypeScript code after it has been webpacked in Visual Studio

I've configured webpack with ts-loader to transpile and bundle my various TypeScript files. Below are the configurations I am using: tsconfig.json { "compileOnSave": false, "compilerOptions": { "noImplicitAny": true, "noEmitOnError": tru ...

Having trouble reading STL files stored in Azure Blob Storage using Three.js

Currently, I am attempting to utilize the @azure/storage-blob package for the purpose of downloading a STL file blob in order to use it with Three.JS. The code snippet for this process is as follows: const downloadResponse = await containerClient.getBlobCl ...

Searching for two distinct nested key values in Ramda

I am new to Ramda and wondering if it is possible to retrieve two different key values at the same level of an object. Below is the code I have added: In this scenario, the object 'list' contains keywords 'users' and 'employee&ap ...

Exploring the ng-repeat directive's scope

Each item on my list can be highlighted when clicked, using the selectedData class. <div>Remove highlight </div> <ul> <li ng-repeat="data in inputData"> <span title="{{data}}" ng-class="selected ? 'selectedData' : ...

Executing code after finishing a fetch in Next.js

Here is the JavaScript code snippet under question: async function checkAuth() { console.log("3") await fetch(apiUrl+'/auth', { method: 'POST' }).then(response => response.json()).then(result => { ...

While attempting to add an object to the array property in Node.js using Mongoose, an error is encountered

I have a challenge where I need to create a categoryName and then add product properties to push them into the categoryProduct field.. When I attempted this using $push, it resulted in an empty array in the database. Callback Function for creating a prod ...

Update Button Visibility Based on State Change in ReactJS

Currently, I'm utilizing a Material UI button within my React application. Despite changing the state, the button remains visible on the screen. Here's the relevant code snippet: function MainPage() { const state = useSelector(state => sta ...

Verify the occurrence of an element within an array inside of another array

Here is the scenario: const arr1 = [{id: 1},{id: 2}] const arr2 = [{id: 1},{id: 4},{id: 3}] I need to determine if elements in arr2 are present in arr1 or vice versa. This comparison needs to be done for each element in the array. The expected output sho ...

The result of adding up all Object Keys is a String, rather than the anticipated Number

Can anyone assist me with a coding issue I'm experiencing? My goal is to sum up all the values of an object and store them in a single variable for the total, but it appears that I am concatenating them instead. binance.depth("BNBBTC", (error, depth, ...

Issue with Image display when UpdatePanel is triggered

I'm currently in the process of developing a website using ASP.NET and C#. Within this site, I have implemented 2 sets of Image Banners. The first set is static and does not change, featuring images based on my C# code. <div class="divArticleCar" ...

When using React Router with Suspense for lazy loading, my notFound page consistently displays beneath all of my components

I have a component that generates dynamic routes using a list called routes[], but whenever I add the route for the "not found" page NotFoundUrl, it always displays it in all components. All the other routes work perfectly fine, but when adding the 404 ro ...