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

Issues with the .change(function() JavaScript in Internet Explorer versions less than 9

I'm experiencing issues with this script in Internet Explorer versions below 9. Can someone please help me identify what is wrong with my script? Thank you. IE7 and IE8 are showing the following error: SCRIPT87: Invalid argument. Found ...

The API response indicates that the service is currently not accessible

I'm attempting to retrieve a report from the MOZ API, but I keep receiving this response: { "status" : "503", "error_message" : "Service Temporarily Unavailable" } This is the code I am using: function MozCall(callback) { var mozCall = ' ...

When representing audio as sound bars on a canvas, the previous drawing is retained if canvas height is not specified

After obtaining an audioBuffer containing an audio clip, I proceed to create a visualization by drawing a series of sound bars in the shape of a circle: const { audioContext, analyser } = this.getAudioContext(); const source = audioContext.createBufferSou ...

How to iterate through the elements of an object within an array using Vue.js and TypeScript

There was an issue with rendering the form due to a TypeError: Cannot read properties of undefined (reading '0'). This error occurred at line 190 in the code for form1.vue. The error is also caught as a promise rejection. Error Occurred <inpu ...

Error found in event.PreventDefault()

I'm currently implementing Twitter Bootstrap on my application. I added e.preventDefault for the link button within $(document).ready(), but it doesn't seem to be functioning properly. Below is the code snippet: Master page: <a id="lnkLogou ...

How to Use PHP to Submit Form Information

I am a beginner in PHP and I need help with sending form details to an email address. I have tried looking for solutions online but I keep running into the same issue - when I submit the form, it downloads the PHP file instead of sending an email. Below i ...

Adjust the dimensions of the dropdown menu

Objective: How can I adjust the width of a select dropdownlist that is utilizing bootstrap v2? Challenge: I am uncertain about how to modify the width in the context of bootstrap. Additional Information: Keep in mind that there are three dropdownli ...

The specified property cannot be found within the type 'JSX.IntrinsicElements'. TS2339

Out of the blue, my TypeScript is throwing an error every time I attempt to use header tags in my TSX files. The error message reads: Property 'h1' does not exist on type 'JSX.IntrinsicElements'. TS2339 It seems to accept all other ta ...

Browserify - combine external modules into a single bundle

I am a complete beginner in the world of browserify. I recently discovered this interesting module called peer-file, which allows for file transfer between two browsers. After reading the Usage section in its readme, I realized I needed to include the scri ...

A recursive function enhanced with a timeout mechanism to avoid exceeding the stack call limit

Trying to search for images on any object of various depths using a recursive function can lead to a Maximum call stack size exceeded error in certain cases. A suggested solution here involves wrapping the recursive function in a setTimeout, but this seems ...

Utilizing a class instance as a static property - a step-by-step guide

In my code, I am trying to establish a static property for a class called OuterClass. This static property should hold an instance of another class named InnerClass. The InnerClass definition consists of a property and a function as shown below: // InnerC ...

Executing Node.js Function from an External File Dynamically

Is it possible to run a Node function from an external file that may be subject to change? main.js function read_external(){ var external = require('./external.js'); var result = external.result(); console.log(result); } setInterva ...

Using jQuery to update the input value when the mouse hovers over a div

Attempting to update an input value using jQuery mouseover. Situation: There are 5 divs with different colors and usernames. When hovering over a div, the input text (and background color for the color input) changes based on database values. Each time a ...

Adjusting the minimum value on a textfield with JQuery Validate plugin in real-time

I am attempting to dynamically update the minimum value on one field based on input from other fields. Here is a brief overview of my code: $("#new_project").on("click", function() { switch($('input:radio[name=quality-level]:checked').val() ...

Node.js does not allow for the usage of `.on` to monitor events until the client has been

I'm currently working on developing a WhatsApp chatbot using the whatsapp-web-js package. However, I am facing some difficulties with implementing it due to my limited knowledge in node JavaScript and async code. let client; //To establish connection ...

Can you help me streamline the code for the Sign Up Form app using React and jQuery?

Hi everyone, this marks my debut post on StackOverflow as I embark on the journey to become a full stack developer. To enhance my skills, I've been using FrontEnd Mentor for practice and managed to solve a challenge with the code provided below. Any s ...

I want to know how to shift a product div both horizontally and vertically as well as save its position in And Store

How can I animate and move a product div horizontally & vertically, and save its position for future visits? I need to move the div with animation in a specific sequence and store the position using PHP. Buttons <button type="button" href ...

What is the best way to pass parameters to a PHP script using AJAX to ensure they are properly processed on the server side?

I'm working with the following function: function myFunction () { $.getJSON('remote.php', function(json) { var messages = json; function check() { ... In this function, I call the remote.php script which e ...

In Javascript, ensuring a stopping condition for a recursive function that is looping through JSON data

I am having trouble figuring out how to set the break condition for this recursive function. Currently, the function is causing the browser to freeze (seems to be stuck in an endless loop). My goal is to create a series of nested unordered lists based on ...

Creating an identifier for the jQuery slideToggle function involves assigning a unique class or ID to

I am currently working on creating an identifier for the jQuery slide.Toggle function. In my PHP code, I have a loop that prints values, each with a button and a div that should be able to slide toggle. So far in PHP, here is what I have attempted, withou ...