Comparing elements in one array to elements in another array

In AngularJS, the $scope.categories array is populated from a multi-select element.

$scope.categories = ["Adventure", "Strategy"]

To compare this array with the categories in the items array below:

$scope.items = [
    {
        title: "Star Wars",
        categories: ["Adventure"]
    }, {
        title: "Star Search",
        categories: ["Adventure", "Strategy"]
    }, {
        title: "Star Trek",
        categories: ["Adventure", "Family"]
    }, {
    title: "Star Wars",
    categories: ["Family", "Strategy"]
}];

The values in $scope.categories must match those in $scope.items.categories for an object to be pushed to an output array.

The resulting $scope.filtered array will be (items1):

{
  title: "Star Search",
  categories: ["Adventure", "Strategy"]
}

I have the logic up until the point where the loop needs to iterate again... how can I achieve this?

  1. I loop through $scope.categories
  2. I then loop through $scope.items
  3. I then loop through each object's $scope.item.categories array.
  4. I compare the value of $scope.categories with the value of $scope.item.categories

    for (var i = 0; i < categories.length; i++) {
      for (var j = 0; j < items.length; j++) {
        for (var k = 0; k < items[j].categories.length; k++) {
          if(categories[i] == items[j].categories[k]) {
            console.log("The value of " + categories[i] + ", matches " + items[j].categories[k]);
          } else {
            console.log("The value of " + categories[i] + ", is not a match");
          }
        }
      }
    }
    

Check out this JSbin example!

Answer №1

It's really quite simple:

var filtered = items.filter(function(i) {
  return categories.every(function(c) {
    return i.categories.indexOf(c) >= 0
  })
})

Array.prototype.filter goes through an array and executes a callback function for each item. If the callback function returns true for an item, it is included in the resulting array.

Array.prototype.every iterates over an array and runs a callback function for each item. It returns true if all callbacks return true, otherwise false.

In this scenario, we are filtering the items array based on whether all of the categories meet the condition set by the every callback - that the item must contain all current (c) categories.

(Check out the updated JSBin)

Answer №2

Presented here is a more straightforward approach. It operates under the assumption that ordering and capitalization must be adhered to strictly. Interestingly, the combination of filter and join method proves to be more efficient compared to using filter along with every method. If we consider top-level categories (such as

var categories = ["Adventure", "Strategy"]
) as a subset, then incorporating the join() function alongside indexOf can enhance simplicity while still slightly boosting performance.

To assess performance, you can check the test link: http://jsfiddle.net/t3g3k7tL/.

var categories = ["Adventure", "Strategy"];

var items = [
    {
        title: "Star Wars",
        categories: ["Adventure"]
    }, {
        title: "Star Search",
        categories: ["Adventure", "Strategy"]
    }, {
        title: "Star Trek",
        categories: ["Adventure", "Family"]
    }, {
        title: "Star Wars",
        categories: ["Family", "Strategy"]
    }
];

var filtered = items.filter(function(element) {
    return element.categories.join("") === categories.join("");  
});

If the top-level categories are considered a subset rather than an exact match, this alternative solution could be applied:

var filtered = items.filter(function(element) {
    return element.categories.join("").indexOf(categories.join("")) !== -1;    
});

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

Leveraging the power of jQuery Validation in conjunction with Bootbox

I am currently facing an issue with integrating the jQuery validation plugin with bootbox.js (modals). The modal contains a form with fields that require validation. To showcase my problem, I have set up a jsFiddle here: http://jsfiddle.net/rDE2q/ Upon ...

Switch the cursor to display the magnifying glass icon for zooming in and out

I am curious about how to modify the cursor shape to display a zoom in and zoom out symbol. Changing the cursor to indicate busy or wait status is something I am familiar with, document.manual_production.style.cursor='wait'; However, I am unsu ...

How does the function window.open determine whether to open a new tab or switch to an existing tab based on specific criteria?

As I navigate through new tabs and existing tabs, I am curious about the criteria that determines whether a new tab is opened or if the browser simply reopens an existing tab with the same name. Could someone shed light on the specific parameters being co ...

What steps are involved in implementing an ordering system on a restaurant's website using React?

As I work on developing my portfolio using React, I'm interested in incorporating an online ordering feature. However, the information I have found through Google so far hasn't fully addressed my questions. Can anyone provide guidance on the best ...

Find the value within the array that includes all the characters, regardless of their order, and then return that

After thorough searching, I am left with no choice but to inquire. Within my array, I possess the following elements: ["123456","132457", "468591", ... ]. Furthermore, I hold a string with the value of "46891". My dilemma lies in how to navigate through ...

Whenever I attempt to include additional drop-down lists, jQuery fails to function

My webpage features multiple drop down lists, with one populating based on the selection from another. Additionally, I have included a button at the bottom of the page. When this button is clicked, I need to add another column to the page. However, after ...

Conceal a different div unless it includes

Hi everyone, I need help with a filter code snippet: $(".title").not(":contains('" + $("[name=filter]").val() + "')").hide() The issue I'm facing is that the .title class is nested within the .sortAll class along with many other divs. I w ...

working with the express locals function

I've been trying to come up with a function that can access local variables, such as this one: // Retrieve user data by ID res.locals.findUser = function(user_id) { models.user.findOne({ '_id': user_id }, function(err, user) ...

@vue/cli for automated unit testing

I'm currently using @vue/cli version 4.5.15 and looking to write tests for my components. However, when I run the command, yarn test:unit I encounter an error that says: ERROR command "test:unit" does not exist. Do I need to perform additional se ...

How to Calculate the Time Interval Between Two CORS Requests Using jQuery AJAX

When using jQuery's $.ajax to make a CORS request to a web service, there is typically a pre-flight request followed by the actual POST request. I have observed that when there is a time gap between making two web service calls, both a pre-flight and ...

What is the most effective way to access content from a webpage that is rendered

Is there a reliable way to download from links on a JavaScript rendered webpage using Python as the preferred language? I have attempted to use the Selenium Python bindings on a headless server, but it has proven to be slow, error-prone, and unable to acc ...

Exploring the world of Node.js callback parameter passing

Currently, I am diving into the world of Node callbacks and JavaScript in general. As I delve deeper, I find myself puzzled by the following snippet: var request = require('request'); request('http://www.google.com', function (error, ...

Utilizing hover effects and timeouts to conditionally show React components

I encountered a challenging React layout dilemma. It's not a complex issue, but rather difficult to articulate, so I made an effort to be as clear as possible. The data I have maps individual components in the following way: map => <TableRow na ...

What is the best way to conditionally wrap a useState variable in an if statement without losing its value when accessing it outside the if block in reactjs?

I am facing a coding challenge with my cards state variable in React using the useState hook. I tried adding my array data to it but ended up with an empty array. Placing the state inside an if statement resulted in undefined variables. I attempted various ...

JavaScript error: forEach is not a function

I've encountered an issue while attempting to loop through a JSON object to extract data. Whenever I run my code, I receive this error: Type Error: element.listing.forEach is not a function. It's worth mentioning that I've used this method ...

Using Angular service worker to pre-fetch video files

Issue arises when the service worker prefetches the entire video embedded on the page, leading to performance problems. My ngsw-config.json only contains configurations for local files, whereas the video is located on a different subdomain under /sites/def ...

Turn off javascript on a website that you are embedding into another site

Is it feasible to deactivate JavaScript on a website you are attempting to embed? If the website is working against your embedding efforts, could you effectively neutralize all their JavaScript, even if it requires users to engage with the site without J ...

How can data be transmitted to the client using node.js?

I'm curious about how to transfer data from a node.js server to a client. Here is an example of some node.js code - var http = require('http'); var data = "data to send to client"; var server = http.createServer(function (request, respon ...

Is there a way to halt the compiler until an Ajax request is fully processed?

Within my form, there is a field labeled parent keywords as a secret key. The validation of this form using JavaScript functions smoothly. It is designed to check if the secret key is associated with any parent or not. If not, the value is set to 0 by defa ...

Form a bond with the latest SignalR library to initiate communication

After attempting to connect to an asp.net core signalR server using the code below, I encountered some issues. Can you spot where I might have gone wrong? Here is the error message that I received: Error: The "promise" option must be a Promise v ...