How to eliminate duplicate items in an array using various criteria

I have an array arr that needs to be cleaned up by removing duplicate objects with the same e_display_id and e_type as P. In this scenario, only objects with status==='N' should be considered.

Here is the input array arr:

let arr = 
  [ { e_type: "P", e_record_id: 33780, e_display_id: "EA-15-001", status: "Y" } 
  , { e_type: "P", e_record_id: 33744, e_display_id: "PE-14-016", status: "N" } 
  , { e_type: "P", e_record_id: 33386, e_display_id: "PE-14-016", status: "Y" } 
  , { e_type: "P", e_record_id:   420, e_display_id: "PE-14-911", status: "Y" } 
  , { e_type: "P", e_record_id:   421, e_display_id: "PE-14-911", status: "N" } 
  , { e_type: "R", e_record_id: 33386, e_display_id: "PE-14-016", status: "Y" } 
  , { e_type: "R", e_record_id: 33386, e_display_id: "PE-14-016", status: "Y" } 
  ];

My approach includes:

I'm utilizing lodash methods to filter out objects with e_type as P, then identifying any duplicate e_display_id. If duplicates exist, I am retaining only those with status as N.

let clonedPursuits = [...arr];
let myarr = _.filter(clonedPursuits, x => x.e_type === 'P');
const counts = _.countBy(myarr, 'e_display_id');
clonedPursuits = _.filter(myarr, x => counts[x.e_display_id] > 1);
const uniqueAddresses = Array.from(new Set(clonedPursuits.map(a => a.e_display_id)))
                          .map(id => {
                 return clonedPursuits.find(a => a.e_display_id === id && a.status === "N");
                           });
console.log(uniqueAddresses);

Expected Result:

[ { e_type: "P", e_record_id: 33780, e_display_id: "EA-15-001", status: "Y" } 
, { e_type: "P", e_record_id: 33744, e_display_id: "PE-14-016", status: "N" } 
, { e_type: "P", e_record_id: 421, e_display_id: "PE-14-911", status: "N" } 
, { e_type: "R", e_record_id: 33386, e_display_id: "PE-14-016", status: "Y" } 
, { e_type: "R", e_record_id: 33386, e_display_id: "PE-14-016", status: "Y" } 
];

Current Output:

[ { e_type: "P", e_record_id: 33744, e_display_id: "PE-14-016", status: "N"} 
, { e_type: "P", e_record_id: 421, e_display_id: "PE-14-911", status: "N"} 
] 

Answer №1

I have successfully completed the task:

const arr = 
  [ { e_type: "P", e_record_id: 33780, e_display_id: "EA-15-001", status: "Y" } 
  , { e_type: "P", e_record_id: 33744, e_display_id: "PE-14-016", status: "N" } 
  , { e_type: "P", e_record_id: 33386, e_display_id: "PE-14-016", status: "Y" }
  , { e_type: "P", e_record_id:   420, e_display_id: "PE-14-911", status: "Y" }
  , { e_type: "P", e_record_id:   421, e_display_id: "PE-14-911", status: "N" } 
  , { e_type: "R", e_record_id: 33386, e_display_id: "PE-14-016", status: "Y" } 
  , { e_type: "R", e_record_id: 33386, e_display_id: "PE-14-016", status: "Y" } 
  ] 

const res = arr.reduce((a,c,i,t)=>
  {
    if (c.e_type!=='P')
      a.push({...c})
    else
    {
      if (c.status==='N')
        a.push({...c})
      else if (!t.some(x=> x.e_type==='P' && x.e_display_id===c.e_display_id  && x.status==='N' ))
        a.push({...c})
    }
    return a
  },[])

console.log( res )

console.log( ' --------- original array direct removing:-----------------')
// If you prefer to delete the elements directly without creating another array:

for(let i=arr.length;i--;)
{
  let c = arr[i]
  if (c.e_type!=='P') continue
  if (c.status==='N') continue
  if (!arr.some(x=> x.e_type==='P' && x.e_display_id===c.e_display_id  && x.status==='N' )) continue
  arr.splice(i,1)
}
console.log(  arr )
.as-console-wrapper { max-height: 100% !important; top: 0; }

Answer №2

Here's a solution that may work for you. One advantage is its efficiency, as it only makes two passes through the array resulting in an O(n) time complexity. However, a downside is that it doesn't maintain the order of items, requiring them to be re-sorted with an O(nlog(n)) complexity.

The concept behind this approach involves identifying and including certain items on the initial pass through the list while also noting which e_display_id values were encountered and their respective statuses. On the second pass (examining what was seen but not added), determining what should be added based on the established criteria becomes straightforward.

let arr = [ 
  { e_type: "P", e_record_id: 33780, e_display_id: "EA-15-001", status: "Y" },
  { e_type: "P", e_record_id: 33744, e_display_id: "PE-14-016", status: "N" },
  { e_type: "P", e_record_id: 33386, e_display_id: "PE-14-016", status: "Y" },
  { e_type: "P", e_record_id:   420, e_display_id: "PE-14-911", status: "Y" },
  { e_type: "P", e_record_id:   421, e_display_id: "PE-14-911", status: "N" },
  { e_type: "R", e_record_id: 33386, e_display_id: "PE-14-016", status: "Y" },
  { e_type: "R", e_record_id: 33386, e_display_id: "PE-14-016", status: "Y" } 
];

let seen = {};

let filtered = arr.reduce((res, curr) => {
  let type = curr.e_type;
  let status = curr.status;
  let id = curr.e_display_id;
  if (type !== "P") {
    res.push(curr);
  }
  else {
    if (!seen[id]) { seen[id] = {}; }
    if (!seen[id][status]) { seen[id][status] = []; }
    seen[id][status].push(curr);
  }
  return res;
}, [])

let finalResults = filtered.concat(Object.values(seen).reduce((res, curr) => {
  if (curr["N"]) { res.push(...curr["N"]); } 
  else if (curr["Y"] && curr["Y"].length === 1) { res.push(...curr["Y"]); }
  return res;
}, []))

console.log(finalResults);

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

The AJAX call was successful, however, the response did not contain any data

I have a MySQL table where I use a FOR EACH loop to display data on my page. I then make an AJAX request to update the displayed data every time a new row is inserted into the database. Although the AJAX request is successful, it returns empty data. I&apo ...

Querying with mongodb using the $or operator yields a single result

I need help querying my MongoDB using JavaScript as I am only getting one result when I should be utilizing the $or operator. The frontend sends a string, which I then split by spaces to search for matches in the database based on skills, location, and na ...

Automatically collapse the Shadcn-UI Accordion when the mouse exits

For my self-education project, I am working on building a sidebar with an accordion using Shadcn-ui, NextJS (13.4), React, and Node. Being new to these technologies, I have encountered a problem that I can't seem to solve. The sidebar expands on mous ...

reactjs implementation of a virtualized list

Recently, I stumbled upon the React-window library and found it to be incredibly useful. Intrigued by how it was built, I decided to try my hand at creating my own virtualized list. However, I encountered an issue where the list could only scroll up to it ...

Troubleshooting TypeScript Modules in Visual Studio 2015 Update 2: Fixing the 'require' Undefined Error

While working in Visual Studio 2015 Enterprise with Update 2 installed, I decided to create a new TypeScript project called TypeScriptHTMLApp1 using the default template and settings. As part of this project, I added a new TypeScript file named log.ts and ...

Guide on how to receive multiple responses from a single ajax request in PHP

I am in the process of developing a web application that includes a search feature. When a user enters a name to search for, I use an AJAX request to retrieve and display records related to that specific person. However, due to the extensive amount of info ...

Utilize the Masonry layout script on dynamically generated elements from AJAX requests

I have been implementing a Masonry script with the following code: var $container = $('.grid'); $container.imagesLoaded(function(){ $container.masonry({ itemSelector : '.grid-item', columnWidth : '.grid-sizer', ...

What are the differences between using embedded documents and references in a mongoose design model?

I am currently in the process of developing a discussion forum using Node.js and mongoose. The structure I have in mind involves users being able to participate in multiple forums, with each forum containing multiple comments. Additionally, users should ha ...

JavaScript JSON conversion from a list

If I have two different lists, such as: list1= ['blue', 'green', 'purple'] list2 = ['circle', 'square', 'triangle'] Is there a way to convert them into a JSON object structure by using another l ...

The updating of Angular 2 CLI variables does not occur

As a complete newcomer to Angular 2, I recently attempted to start my first project using the Angular CLI. Unfortunately, I encountered some issues. It seems that the variables in my views are not updating as expected. I followed the typical steps: ng n ...

Align Horizontal Fixed Element

<html> <head> <style> #rectangle { position: absolute; right: 0; bottom: 0; width: 150px; height: 200px; } </st ...

Breaking apart web addresses and their attached parameters

I am attempting to extract the part of a URL that comes after the last forward slash (/) and before the querystring. While I have been successful in obtaining the last segment of the URL, I have encountered difficulty in removing the querystring from it. ...

Utilizing Node.js to iterate through arrays grouped by categories

Here is some data I need to work with [ [ '@test','1.2.6-unstable' ], [ '@test','1.3.2-unstable' ], [ '@test','1.4.6-unstable' ], [ '@test2','4.0.1-unstable' ], [ &ap ...

Achieve a fading effect on an element as you scroll down the page

I successfully implemented a toggle audio button on my website, but now I would like it to fade in along with the scroll-to-top button that I also have (which operates similarly to the buttons on scrolltotop.com). Is there a simple way to achieve this? He ...

Searching for data in a bootstrap table that is not case-sensitive

Searching for and highlighting text within a bootstrap table has proven to be a challenge. Check out the Fiddle for an example: https://jsfiddle.net/99x50s2s/74/ HTML <table class='table table-bordered'> <thead> <tr& ...

Retrieve the variable only once a response has been received from the POST request

Is there a way to update a variable in my component only after receiving a response from a POST request? Here is the code in component.ts: formSubmit() { this.sent = this.submitProvider.sendByPost(this.form); this.formSent = this.submitProvider.f ...

Do we need to have the 'input type file' field as

I am currently working on a PHP form that includes mandatory fields for saving the data. For example: <td><input class="text_area required" type="text" name="new field" This form also has Javascript code with file upload functionality, which I ...

Adjusting the alignment of a facial image on Canvas by selecting specific click-points

I have a unique idea for an app that allows users to correct a tilted face with just 2 clicks The concept is simple - users click on the middle of the nose and the middle of the eyebrows within the image to generate two points: eyebrowMiddle(x1,y1) and no ...

Exploring AngularJS $compile and the concept of scoping within JavaScript windows

I've encountered a scoping issue with the use of this inside an angular-ui bootstrap modal. The code below functions perfectly outside of a modal, but encounters problems when run within one: var GlobalVariable = GlobalVariable || {}; (fun ...

Retrieve an array object containing specific properties using axios

Currently, I am retrieving JSON data from an API call using axios and displaying it through Vue. This snippet shows the JSON Object logged in the console: 0: category_id: "categ1" item_name: "item1" price: 100 stock: 155 1: c ...