Filter an array of objects based on criteria from another array

CustomArray.prototype.erase = function() {
  var target, args = arguments,
    length = args.length,
    index;
  while (length && this.length) {
    target = args[--length];
    while ((index = this.indexOf(target)) !== -1) {
      this.splice(index, 1);
    }
  }
  return this;
};

var data = [{
  title: 'Bookable',
  start: moment("2018-04-05 06:00"),
  end: moment("2018-04-05 07:00"),
  allDay: false
}, {
  title: 'Bookable',
  start: moment("2018-04-05 06:00"),
  end: moment("2018-04-05 07:00"),
  allDay: false
}, {
  title: 'Bookable',
  start: moment("2018-04-05 06:00"),
  end: moment("2018-04-05 07:00"),
  allDay: false
}, {
  title: 'Bookable',
  start: moment("2018-04-05 06:00"),
  end: moment("2018-04-05 07:00"),
  allDay: false
}]

var targetsToRemove = [{
  title: 'Bookable',
  start: moment("2018-04-06 06:00"),
  end: moment("2018-04-06 07:00"),
  allDay: false
}];
console.log("Before: " + data.length)
for (var i = 0; i < targetsToRemove.length; i++) {
  data.erase(moment(targetsToRemove[i].start).format("YYYY-MM-DD HH:mm"));
}
console.log("After: " + data.length)
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.0/moment.js"></script>

I aim to eliminate certain elements from one array by using another as a guide. Both arrays consist solely of objects similar to the one below. All corresponding objects in targetsToRemove should be deleted from the data array. The start property seems suitable for this purpose, but there is no Id.

The object structure is:

   var item = {
                            title: 'Bookable',
                            start: moment(datesValue + " " + hourValue.start),
                            end: moment(datesValue + " " + hourValue.end),
                            allDay: false
                        };

Prototype.remove

       CustomArray.prototype.erase = function () {
        var target, args = arguments,
            length = args.length,
            index;
        while (length && this.length) {
            target = args[--length];
            while ((index = this.indexOf(target)) !== -1) {
                this.splice(index, 1);
            }
        }
        return this;
    };

Usage example:

  for (var i = 0; i < targetsToRemove.length; i++) {
                            data.erase(moment(targetsToRemove[i].start).format("YYYY-MM-DD HH:mm"));
                        }

An error

Cannot read property 'indexOf' of undefined
occurs with this code, causing all objects to be removed. An unsuccessful demonstration is also provided. Any suggestions on improving this removal process are welcomed.

Your assistance is greatly appreciated.

Answer ā„–1

From my understanding, the remove function requires the same exact element and may not work effectively with complex elements.

I recommend using Array.prototype.filter:

var items = [{
  title: 'Bookable',
  start: moment("2018-04-05 06:00"),
  end: moment("2018-04-05 07:00"),
  allDay: false
}, {
  title: 'Bookable',
  start: moment("2018-04-05 06:00"),
  end: moment("2018-04-05 07:00"),
  allDay: false
}, {
  title: 'Bookable',
  start: moment("2018-04-05 06:00"),
  end: moment("2018-04-05 07:00"),
  allDay: false
}, {
  title: 'Bookable to remove',
  start: moment("2018-04-06 06:00"),
  end: moment("2018-04-06 07:00"),
  allDay: false
}]

var datesToRemove = [{
  title: 'Bookable',
  start: moment("2018-04-06 06:00"),
  end: moment("2018-04-06 07:00"),
  allDay: false
}];

for (var i = 0; i < datesToRemove.length; i++) {
  var toRemove = datesToRemove[i];
  items = items.filter(function(element) {
    return element.start.valueOf() != toRemove.start.valueOf();
  });
}

console.log(items);
<script src="https://momentjs.com/downloads/moment-with-locales.min.js"></script>

Answer ā„–2

Avoid extending the native Array prototype unnecessarily. JavaScript offers built-in methods for Array manipulation that can effectively solve your problem without risking unintended side effects associated with custom Array methods and for loops. Custom methods may mutate original data structures, hindering reusability and complicating debugging efforts in the future. Built-in Array methods maintain the integrity of original data structures by creating shallow copies during manipulation, allowing for seamless chaining of operations.

  • .map()
  • .filter()
  • .reduce()

Another commonly used Array manipulation method is .forEach(), which simplifies iteration without the need for traditional for loops. Unlike other methods, .forEach() does not prevent mutation of original data structures. It can be combined with other Array methods but breaks the chain once invoked.

.map(), .filter(), and .reduce() offer a functional approach to iterating over and manipulating arrays. Each method serves a unique purpose and understanding their distinctions is essential for effective chaining.

.MAP()

  • .map(): Similar to .forEach(), this method iterates over each item in an Array and applies a function for transformation, producing a new Array with transformed values. The length of the resulting array always matches the original, making it ideal for value transformations.

Example:

const originalArr = [1, 2, 3, 4, 5]
const incrementedArr = originalArr.map(n => n + 4)

console.log(originalArr)     // [1, 2, 3, 4, 5]
console.log(incrementedArr)   // [5, 6, 7, 8, 9]

.FILTER()

  • .filter(): Iterates over each item in an Array and filters based on a provided condition, returning a subset of items that meet the criteria. This method is useful for creating a new Array with a different length based on filtering conditions.

.REDUCE()

.reduce() allows for reducing an Array into an Object using specific parameters. While more complex, it complements .map() and .filter() for comprehensive manipulation.

THE SOLUTION

// Arrays containing items and dates to remove

const items = [{}, {}, {}, {}]
const datesToRemove = [{}]

// Dedupe merged arrays
const mergeUniqueMatches = catArr => catArr.filter((elem, pos, arr) => arr.indexOf(elem) == pos)
const mergedArr = mergeUniqueMatches(items.concat(datesToRemove))

// Alternative deduping method
const dedupedArr = [...new Set(mergedArr)]

// Further steps depend on clarification regarding data structure

Consider assigning unique identifiers to objects to simplify removal operations. Utilize modern ES6/7 features like destructuring to streamline array manipulations.

// Destructuring option with ES6
const destructingOptionWithES6 = { ...items, ...datesToRemove }

// Filter out unwanted items
const ideallyAllYouShouldHaveToDoIsThisFunction = items.filter(val => !datesToRemove.includes(val))

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

My NodeJS MongoDB application is being bombarded by an infinite loop of "Sending request..." messages from the Postman

This is the complete code for my chatbot application const express = require('express'); const app = express(); const MongoClient = require('mongodb').MongoClient; const assert = require('assert'); const bodyParser = require(& ...

Excluding form items that are disabled from a request in ReactJS

In my code, I am dealing with a Form section that contains multiple Collapse.Panel sub-sections. Interestingly, the Form.Item elements within collapsed panels are not included in the form values upon submission. However, I have noticed that certain InputNu ...

Interactive hover effect in JavaScript displays a larger version of other thumbnails when hovering over a dynamically loaded thumbnail image, instead of its own full-size image

I recently began teaching myself PHP and Dreamweaver with the help of a video tutorial on building data-driven websites using Dreamweaver. My goal is to create a dynamic table with 6 columns and 20 rows. column1 | column2 | column3 | colu ...

Creating a unique Angular filter involves combining different techniques and functionalities to tailor

Hey there! I'm just diving into the world of Angular JS and I'm looking to filter any Twitter text that comes back containing a hashtag, and turn that word into a clickable link. For example: If the returned twitter text is "The quick brown #f ...

My Discord.JS bot seems to be moving at a snail's pace, and I can

Apologies for the lackluster title, I'm struggling to come up with something better. I'm currently running a self-bot (I understand it goes against the terms of service but I'm experimenting) that needs to download new files (specifically i ...

Effective technique for connecting client-side JavaScript with server-side node.js

I am striving to create a compact website featuring field auto-completion, drawing suggestions from the server's database (utilizing Node.js + MySQL). What approaches can I take to establish client-server communication as the user inputs data into a ...

Attempting to iterate over a JSON object and display its contents using HTML

I have been attempting to iterate through this JSON data and display it in an accordion format similar to the one shown here: but unfortunately, my implementation is not functioning correctly. Here is what I currently have: HTML: <div class="a ...

Exploring the combination of Express router, Auth0, and plain Javascript: A guide to implementing post-login authentication on a router

After creating a front end with vite using vanilla javascript and setting up a backend with node.js express routes, I successfully integrated swagger for testing purposes. I have managed to enable functionalities such as logging in, logging out, and securi ...

Discovering the ways to declare an array type in Haskell

Creating a linked-list type in functional languages like Haskell is straightforward, as shown by the simple definition: data List a = Nil | Cons a (List a) However, I have not come across any tutorials that explain how to define your own array type from ...

Tips for identifying if the function "res.end()" has been executed or not

Is there a method to determine if the res.end function has been triggered? var http = require('http'); http.createServer(function (req, res) { some_function_may_called_end(req, res); // Is there a way to check for this? if(res.is_ended = ...

Converting a jQuery DOM element into a string representation

Currently, I am working with a textarea that contains the contents of an HTML file. This textarea includes all elements of my HTML page such as doctype, head, html, etc. My goal is to save the content of the textarea into a DOM variable using $.parseHTML: ...

Can you tell me how to display the currently utilized Node.js version and path within npm?

Iā€™m encountering a similar issue to the one discussed in this Stackoverflow thread: SyntaxError: Use of const in strict mode?. However, my problem arises when attempting to install Flux. I followed the steps outlined in the linked Stackoverflow question ...

Utilize JavaScript to send an email containing a link and content

In the html form, there are input fields for adding a new user to the database. Once a user is added, an email is sent to them using the sendmail() function in the adduser.js file. The email is sent successfully according to my standards. However, I want t ...

What is the reason behind plugins frequently neglecting to properly privatize their functions?

Many plugins utilize an underscore to indicate a function is private while still allowing public access. But why? We have options like .call, .apply, or .bind for managing the "this" keyword, or we can use the "self" pattern which is reportedly 60% faster ...

Problem with Handlebars: When compiling, TypeError occurs because inverse is not recognized as a function

I've hit a roadblock with an error that I just can't seem to solve. My goal is to dynamically compile a template extracted from a div on the page, provide it with content, and then display it in a designated area of my webpage. Here's the s ...

Is it recommended to use separate Controllers for each tab in Angular JS to load the pane?

Recently delving into the world of Angular JS and eagerly seeking expert advice and suggestions. Would it be advisable to use separate controllers for initializing each Tab to load the Pane content? Is assigning separate controllers a recommended approac ...

What is the best way to eliminate the first, second, and final elements of an array?

I have an array and I am currently using the array_splice function to remove elements at specific indices. However, I also want to remove the last element from the array. Is there a way to achieve this? array_splice($arr, 0, 2); // Code to remove first t ...

Having difficulty getting the Mustache.js bundle to function properly through NPM

I am currently bundling 6 different modules in Webpack, including Mustache.js. The challenge I am facing is that the Mustache templates are located within the HTML page itself and not in a separate file. Upon loading my page, I encounter an error which can ...

Order objects in a JavaScript array

Recently, I came across a list of student data fetched from an API: const Studentdata = { "StudentName1": { "active": true, "gender": "male" }, "StudentName2": { "active": false, "gender": "male" }, "S ...

Centering div elements in ASP.NET using C# and Javascript

I am looking to create a functionality on my website where, upon clicking a button, a DIV appears in the center of the browser, overlaying all other content. I have already created the DIV and managed its visibility toggle, but I'm struggling with the ...