Refrain JavaScript - sift through an array of objects based on the values of a primitive array in linear time

I've got an array of objects that looks like this:

[{
      itemType: 'bottle',
      itemId: '111'
    }, {
      itemType: 'bottle',
      itemId: '222'
    }, {
      itemType: 'bottle',
      itemId: '333'
    }]
    

My goal is to efficiently filter it (with a time complexity of O(n)) using a simple array like this:

[ '111', '333' ]
    

The end result should be an array of objects that looks like this:

[{
      itemType: 'bottle',
      itemId: '222'
    }]
    

I initially considered using underscoreJS, but there doesn't seem to be a built-in function for this specific task. Any other suggestions?

Answer №1

To achieve a solution with linear complexity, it is necessary to make a tradeoff in space complexity in order to perform a single linear search through the array. One approach is to convert the array of matches into a set, reducing the id existence lookup from O(ids.length) to O(1), thereby decreasing the total complexity from O(arr.length*ids.length) to O(arr.length) + O(ids.length):

If there is no room for any space tradeoffs, the total complexity will be quadratic: O(arr.length * ids.length).

ES6 implementation O(arr.length) + O(ids.length):

const arr = [{itemType: 'bottle', itemId: '111'},{itemType: 'bottle', itemId: '222'},{itemType: 'bottle', itemId: '333'}];
const ids = ['111', '333'];

function filter(arr, ids) {
  const s = new Set(ids); // O(ids.length) to build the set and use O(ids.length) space
  return arr.filter(item => s.has(item.itemId)); // O(arr.length) to filter the array
}

console.log(filter(arr, ids));

ES5 implementation O(arr.length) + O(ids.length):

var arr = [{itemType: 'bottle', itemId: '111'},{itemType: 'bottle', itemId: '222'},{itemType: 'bottle', itemId: '333'}];
var ids = ['111', '333'];

function filter(arr, ids) {
  var s = ids.reduce(function(s, id) {
    s[id] = true;
    return s;
  }, Object.create(null));

  return arr.filter(function(item) {
    return s[item.itemId];
  });
}

console.log(filter(arr, ids));

Answer №2

Let's start by assuming

let x = [{
    type: 'glass',
    id: '456'
},
 {
    type: 'glass',
    id: '789'
},
{
    type: 'glass',
    id: '012'
}]

AND

let y = [ '456', '012' ]

Therefore, with the help of underscore methods, we can easily achieve this:

_.filter(x, function(item) {
    return !_.contains(y, item.id)
})

Answer №3

Utilizing a Set to create a blacklist enables us to eliminate duplicates and enhance lookup efficiency.

const blacklist = new Set(['111', '333']);
const items = [
    {
        itemType : 'bottle',
        itemId   : '111'
    },
    {
        itemType : 'bottle',
        itemId   : '222'
    },
    {
        itemType : 'bottle',
        itemId   : '333'
    }
];

const filtered = items.filter((item) => {
    return !blacklist.has(item.itemId);
});

The code above demonstrates that filtered consists of objects from the items array whose itemId is not present in the blacklist.

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

I am interested in utilizing a variable's value as an ID within a jQuery function

When working with jQuery, I often use a variable to store values. For example: var x = "ID1"; To utilize the value of this variable as an ID in my jQuery functions, I simply concatenate it as shown below: $('#' + ID1).val(); Thank you for you ...

Tips for extracting the chosen value from a dropdown list within a table cell using JavaScript

Here is an example of an HTML element: <td> <select> <option value="Polygon 47">Polygon 47</option> <option value="Polygon 49">Polygon 49</option> </select> </td> I am looking for a ...

Dawn Break Alarm Timepiece - Online Platform

My buddy recently purchased a "sunrise alarm clock" that gradually brightens to mimic a sunrise and make waking up easier. I had the thought of replicating this effect with my laptop, but I've been facing issues with getting the JavaScript time funct ...

Interactive element for initiating a HTTP request to NodeJS/Express server to trigger a specific function

I currently have a frontend button implemented using nodejs and express for my server-side backend. The button is supposed to trigger a function that controls the Philips Hue API on the backend via an HTTP request. I have experimented with various approac ...

Issue with sync-request when using post data doesn't seem to be functioning

I am currently working on a Node.js application where I need to make synchronous requests. After some research, I came across the sync-request npm package for making these requests. However, when I tried using the code below, I encountered an error with th ...

Sorry, but we couldn't complete your request: User verification unsuccessful: email must be provided

Every time I attempt to save a user's credentials to the mongo database, an error pops up saying: "User validation failed: email: Path email is required." I am clueless as to why this issue keeps happening. It only started occurring when I added the v ...

Connecting a specific URL of an API to a single mobile app: A step-by-step guide

Currently, my API includes a user registration system that is utilized by a mobile application. Most of the URLs are restricted for anonymous users and require a token key for authorization, except for the register URL. The register URL needs to remain op ...

How can I make the columns in Next.js / Tailwind expand horizontally first instead of vertically?

Recently, I decided to customize the Next.js Image Gallery starter for some hands-on experience in full stack development with Next.js. My goal was to create a chronological photo gallery of a recent trip, but encountered an issue where the responsive colu ...

Placeholder fails to appear

After implementing some jQuery validation, I wanted to display a text as a placeholder when the user skipped out of an input field without entering anything. This is the code I wrote: $('input[type="text"]').on('blur', function() { ...

Is nesting directives possible within AngularJS?

Having trouble creating a Directive that includes another directive from the AngularJS UI. Check out my html: <div class="col-md-12" ng-show="continent == '2'"> <my-rating></my-rating> </div> Here is the directiv ...

Angular constantly looping due to $watchCollection being triggered repeatedly

I am interested in monitoring the changes of an object, referred to as x, specifically its properties which are checkboxes. When a user checks a box, it alters the checked property (prop1) to 1. Each property contains certain content, and when enabled, it ...

Using the Node.js mongodb-native library to insert multiple strings as separate documents

node: 8.9.4 mongo: 3.6.3 mongodb-native: 2.2.33 Query: How can I seamlessly insert an array of simple strings as new documents with just one call? I prefer not to pre-process the array before insertion. I'm in search of a magical mongo solution h ...

Struggling to navigate the DOM using JavaScript and looking for guidance?

I have been searching for an answer to this question without any luck. I am wondering if someone can assist me with finding a solution... I need help using JavaScript (not jQuery) to retrieve the class of the following li element when searching for ' ...

The width of the plotbands on the yAxis of a stacked bar graph is adjusting as the series are dynamically toggled,

https://ibb.co/h7tmwtr https://ibb.co/syRTyPG For the first time, I have included 5 plot bands which looked great. However, when I added a series and toggled it on a stacked bar graph, the plot bands' width started increasing. I want to maintain the ...

Check the input in the text box against the selected options to validate it

Currently, I am working on an add contacts page where I am facing the challenge of displaying an error message or highlighting input as invalid if a user tries to enter a contact name that already exists. It seems like one solution could be populating a s ...

Encountered an issue while building npm: "Error: Unable to locate module @restart/context

Lately, I've encountered an issue with npm build after upgrading to the latest version of react-bootstrap (1.0.0-beta.6). While creating an optimized production build... Failed to compile. Module not found: '@restart/context/forwardRef'. P ...

Connecting Vue.JS page to my existing HTML page: A step-by-step guide

While developing my website, I faced a challenge with the structure. The home page was built using traditional HTML/CSS, while the other pages were created in Vue.js. Is there a method to connect these two different types of files? For instance, can I inc ...

prior to activating a state in angular.js, navigate to a distinct controller

Upon loading my website, I have a specific state in mind that I want to be redirected to. Achieving this is made possible through the following code snippet. angularRoutingApp.run(function ($rootScope, $state, $location, $transitions) { $transitions.o ...

To retrieve the first td element by clicking a button within the corresponding row using JQuery

This may seem like a straightforward inquiry, but despite my best efforts, I have been unable to find a solution. I am looking to create a function that will allow me to click a button located in the 3rd td element and display the text from the first td e ...

What is the best way to save a JavaScript variable in local storage?

I am facing an issue with a JavaScript variable named addNumber. This variable is responsible for adding 1 to a div every time a button is clicked. However, the problem arises when I navigate between different pages on my website - the counter resets back ...