Removing an object from an array if it does not exist in another array: A step-by-step

Looking to remove an object from an array if it's not present in another array. After doing some research, I came across a similar question on this link, but with a different array source.

Below is the example from the link:

var check = [1, 2, 3];
var allowed = [1];

var filtered = check.filter(function(item) {
  return allowed.indexOf(item) > -1;
});

console.log(filtered);

The example above removes numbers from the array check if they are not present in the array allowed. In my case, the source array contains objects as shown below:

var check = [
    {
        name: 'Peter',
        location: 'florida'
    },
    {
        name: 'Robert',
        location: 'California'
    }
];

var allowed = [
    {
        name: 'Robert',
        location: 'Boston'
    }
];

var filtered = check.filter(function(item) {
  return allowed.indexOf(item.name) > -1;
});

console.log(filtered);

I ran the code and ended up with an empty array as the result.

Expected result:

[
    {
        name: 'Robert',
        location: 'California'
    }
]

If anyone could help me achieve the expected result, that would be greatly appreciated.

Answer №1

To utilize the Array#find() function

var list = [{
    name: 'Alice',
    location: 'New York'
  },
  {
    name: 'Bob',
    location: 'Texas'
  }
];

var allowedItems = [{
  name: 'Bob',
  location: 'Texas'
}];

var result = list.filter(function(item) {
  return allowedItems.find(function(allowedItem) {
    return item.name === allowedItem.name
  })
})

console.log(result)

Answer №2

To simplify the search criteria, you can map the allowed variable to only include the names you are interested in:

var allowed = [{
    name: 'Robert',
    location: 'Boston'
}]
.map(obj => obj.name);

This will result in an array containing just the names, making it easier to test using indexOf

For example:

var check = [{
    name: 'Peter',
    location: 'florida'
  },
  {
    name: 'Robert',
    location: 'California'
  }
];

var allowed = [{
  name: 'Robert',
  location: 'Boston'
}]
.map(obj => obj.name);

var filtered = check.filter(function(item) {
  return allowed.indexOf(item.name) > -1;
});

console.log(filtered);

Answer №3

To successfully validate against the item names in the specified allowed array, you need to ensure that your comparison is accurate. Currently, you are comparing the items in the allowed array, which are of type object.

Here's where the issue lies:

return allowed.indexOf(item.name) > -1;

Consider this alternative approach:

var check = [
    {
        name: 'Peter',
        location: 'Florida'
    },
    {
        name: 'Robert',
        location: 'California'
    }
];

var allowed = [
    {
        name: 'Robert',
        location: 'Boston'
    }
];

function containsName(name, array){
  return array.find(item => item.name === name);
}

var filtered = check.filter(function(item) {
  return containsName(item.name, allowed)
});

console.log(filtered);

Answer №4

Utilizing the intersect function below, you can find the intersection of keys within any array of objects:

var data = [
    { name:'Alice', location:'New York' },
    { name:'Bob', location:'California'}
];

var criteria = [
    { name:'Bob', location:'Boston' }
];

function getIntersection(data, criteria) {
    var criteriaMap = criteria.reduce(function(map, obj) {
        Object.keys(obj).forEach(function(key) {
            if (!map[key]) {
                map[key] = [];
            }
            map[key].push(obj[key]);
        });
        return map;
    }, {});


    return data.filter(function(item) {
        return Object.keys(item).find(function(key) {
            return criteriaMap[key].indexOf(item[key]) != -1;
        })
    });
}

var result = getIntersection(data, criteria);

var newCriteria = [{ name:'Charlie', location:'Miami' }];
var newResult = getIntersection(data, newCriteria);

console.log('result:', result);
console.log('newResult:', newResult);

Answer №5

There are various methods based on your specific requirements.

  • Dirty Check
  • Specific Attribute Check
  • Nested Object Check

Dirty Check

To perform a dirty check where both arrays have the same memory reference for objects, you can follow this approach:

var firstPerson = {
    name: 'Peter',
    location: 'florida'
}
var secondPerson = {
    name: 'Robert',
    location: 'California'
}

var allowed = [secondPerson];
var check = [firstPerson, secondPerson];

var result = check.filter(item => allowed.includes(item));

console.log(result);

Specific Attribute Check

If you need to check for a specific attribute, you can utilize the find method to compare attributes like name or location between the check and allowed arrays.

var check = [
    {
        name: 'Peter',
        location: 'florida'
    },
    {
        name: 'Robert',
        location: 'California'
    }
];

var allowed = [
    {
        name: 'Robert',
        location: 'Boston'
    }
];


var result = check.filter(checkPerson => allowed.find(allowPerson => allowPerson.name === checkPerson.name));

console.log(result);

Nested Object Check

For checking nested objects, a recursive approach is required. You can use a utility function like deepCompare, which acts as a lightweight alternative to Lodash's isEqual.

var check = [
    {
        name: 'Peter',
        location: {
            street: "fridtjof nansens vei 8511",
            city: "ågotnes",
            state: "buskerud",
            postcode: "8766",
            coordinates: {
                latitude: "50.4828",
                longitude: "-84.6920"
            }
        }
    },
    {
        name: 'Robert',
        location: {
            street: "schillerstraße 69",
            city: "velburg",
            state: "saarland",
            postcode: 72100,
            coordinates: {
                latitude: "30.4655",
                longitude: "9.1938"
            }
        }
    }
];

var allowed = [
    {
        name: 'Robert',
        location: {
            street: "schillerstraße 69",
            city: "velburg",
            state: "saarland",
            postcode: 72100,
            coordinates: {
                latitude: "30.4655",
                longitude: "9.1938"
            }
        }
    }
];


var result = check.filter(checkPerson => allowed.some(allowPerson => deepCompare(checkPerson, allowPerson)));

console.log(result);
<script>
/**
 * Deep Compare
 * @param { * } value first entry value
 * @param { * } other second entry value
 * @param { Boolean } sorted Sort any array before deep comparison
 */
const deepCompare = (value, other, sorted) => {
  if (Object.is(value, other)) return true;

  if (!value || !other || value.constructor !== other.constructor) return false;

  switch (value.constructor) {
    case Array:
      if (value.length === other.length) { return deepArrayCompare(value, other, sorted); }
      return false;
    case Object:
      if (Object.keys(value).length === Object.keys(other).length) { return deepObjectCompare(value, other, sorted); }
      return false;
  }
  return false;
};

const deepObjectCompare = (value, other) => deepArrayCompare(Object.keys(value), Object.keys(other), true) && Object.keys(value).every(key => deepCompare(value[key], other[key]));

const deepArrayCompare = (value, other, sorted) => (sorted && value.sort(), sorted && other.sort(), value.every((item, index) => deepCompare(item, other[index])));
</script>

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

Pass the ID of the <a> element from one function to another

I am a beginner in javascript/jQuery, so please be patient with me if my question seems too simple for you and too challenging for me. I have a function that I won't post the entire code for because it would make this too lengthy. Another function ...

Utilizing the jQuery slideToggle method on the specified target element

I'm encountering an issue with jQuery slideToggle, and here's the code I have: $(".dropdownmainmenu").click(function(){ $(this).children(".showmenu").slideToggle(); $(this).toggleClass("activemainmenu"); $(this).find(".showarrowmainmen ...

Navigating File Paths in Node.js

My directory structure is as follows: Main > models > file1.ejs | |> routes > file2.ejs In my code, I'm trying to require file1 from file2 like this: const variable = require("../models/file1.ejs). But what if I don't want to ...

Installation of a cloned Parse server

I downloaded the Parse server repository from parse-server-example and set up MongoDB, as well as installed Node.js packages using npm install. However, when I try to start the app with npm start, I encounter this error in the terminal!! How can I resolve ...

Tricks for preventing axios from caching in GET requests

I am utilizing axios in my React-Native application Firstly, I set up the headers function setupHeaders() { // After testing all three lines below, none of them worked axios.defaults.headers.common["Pragma"] = "no-cache"; axios.defaults.heade ...

What is the best tool for syntax highlighting with Vue.js?

Looking for guidance on syntax highlighting with Vue.js. I've included the code snippet below, but for some reason the message "This is a test" isn't appearing as expected. Can someone please point out what mistake I may be making? <html> ...

What are the best practices for implementing jquery owlCarousel within an Angular 4 component?

I've included my 'carousel.js' file like this: $('#owl-carousel-1').owlCarousel({...}); and in carousel.component.html, I have: <div id="owl-carousel-1" class="owl-carousel owl-theme center-owl-nav home- carousel">....< ...

Getting an out-of-range exception (System.ArgumentOutOfRangeException) in C# Razor pages while attempting an AJAX call

I have a razor page model that contains a get-method. public IActionResult OnGetDuration([FromBody]int id) { Subject subject = _service.GetSubjectById(id); int duration = subject.LessonsPerWeek; return new JsonResult('a&apo ...

Issue with IE7 Dropdownlist not appearing after changing class name when onFocus event is triggered for the first time

I need to adjust the CSS class of a dropdownlist when it is focused on, in order to change its background color. However, in IE7, when the dropdownlist is clicked, the CSS class changes but the options list does not appear until the dropdownlist is clicke ...

Would you say the time complexity of this function is O(N) or O(N^2)?

I am currently analyzing the time complexity of a particular function. This function takes a string as input, reverses the order of words in the string, and then reverses the order of letters within each word. For example: “the sky is blue” => ...

Tips for obtaining the entire date and time on one continuous line without any breaks or separation

Is there a way to retrieve the current date and time in the format of years, months, days, hours, minutes, seconds, and milliseconds like this? 201802281007475001 Currently, I am getting something like: 2018418112252159 This is my code so far: var dat ...

Utilizing HTML and jQuery to load a dynamic URL within a div placeholder

I'm experiencing some difficulty with loading a custom URL. Essentially, the user will click on a series of navigation links that will dynamically load the relevant content in a tabbed bootstrap jumbotron. The navigation links vary based on data store ...

The integration of the jQuery library within the server side of a Google Apps Container Bound Script

Can the jQuery library be utilized server-side in a Google Apps Script that is Container Bound to a Doc or Sheet? If so, what steps should be taken? In a previous inquiry on Stack Overflow, I sought guidance on incorporating jQuery into a container-bound ...

JavaScript function following AJAX request

I'm attempting to invoke a JavaScript function that is returned in an Ajax call What is the proper way to run a JavaScript function received from an Ajax call? Consider this script before the Ajax call <script> function start(){ console.l ...

Ensuring jQuery filter() works seamlessly with Internet Explorer versions 6, 7, and 8

On my webpage, I have implemented an ajax call using the jQuery library to handle a specific task. After making the ajax call, I need to parse the response message that is returned. However, I encountered an issue with Internet Explorer versions 6, 7, and ...

encountering a type mismatch error while trying to retrieve data from an array

While attempting to retrieve data from a nested array, I encountered the error "TypeError: Cannot read property 'value' of undefined". It seems like I might be calling back incorrectly as I am receiving both the output and the error message in th ...

Safari seems to have trouble running Javascript, unlike all the other browsers which handle it just fine

I've encountered an issue with a script that duplicates form fields when a "Same as Billing" checkbox is checked in one form and transfers the data to another. Everything works smoothly except in Safari, where it fails to transfer the state selection ...

The system encountered an error stating that the required component "Footer" in the main directory was not located in the specified node_modules

Issue I'm Facing: Error found in components/main/Footer within the file path: ./node_modules/babel-loader/lib!./node_modules/vue-loader/lib/selector.js?type=script&index=0!./src/App.vue Components Tree as shown in the screenshot below: https ...

Tips for accessing nested JSON values using Selenium

Here is a JSON snippet to work with: "ACCOUNT": { "AmountDue": "$36,812.99", "OutstandingBalance": "$27,142.27", "StatementTotal": "$9,670.72", "StatementDate": "12/6/2018", "DueByDate": "12/23/2018", ...

What is the process for accessing extra scope information with next-auth?

I have integrated next-auth with Discord authentication and included guilds in my scope, but I am unable to retrieve the guild data. How can this issue be resolved? const options = { providers: [ Providers.Discord({ clientId: process.env.DISC ...