Discover the most effective method for identifying duplicate items within an array

I'm currently working with angular4 and facing a challenge of displaying a list containing only unique values.

Whenever I access an API, it returns an array from which I have to filter out repeated data. The API will be accessed periodically, and the list should be updated only if new data is available.

response= [{"id":"0DRDCH03DR51GGJGJNP80F7XZ8","value":"36af1784bec4_566601260"},{"id":"0DRDCFYGM2CAHAXYK96BPT9RHV","value":"36af1784bec4_566601140"},...]

listData = [];
for(let data of response) {
    let tempValue = {id: '', time: ''};
    let value = data.value.split('_')
    if (value.length==2) {
        if(value[value.length-1].length==2) {
            tempValue.id = value[0];
            tempValue.time = value[1];
        }
        let isPresent = false;
        if(this.listData.length>0){
            for(let value of this.listData){
                if(value.time===tempValue.time){
                    isPresent = true;
                }
            }
        }
        if(!isPresent) {
            this.listData.push(tempValue);
        }
    }

    }

The resulting list:

listData = [{id:'36af1784bec4', time: '566601140'},...]

The above code provides me with a listData array containing unique values. Despite attempting methods like array.filter and new Set, I couldn't achieve the desired outcome.

If you have any suggestions on how to improve the efficiency of this process, please share them with me.

Answer №1

If you're looking to eliminate duplicates, check out this code snippet.

var obj = {};

for ( var i=0, len=response.length; i < len; i++ )
    obj[response[i]['id']] = response[i]; // consider id as unique identifier

response = new Array();
for ( var key in obj )
    response.push(obj[key]);

console.log(response); // list of non-duplicate data 

Edit:

To perform a thorough check on a specific property for duplicates, try this approach.

function removeDuplicates(myArr, prop) {
    return myArr.filter((obj, pos, arr) => {
        return arr.map(mapObj => mapObj[prop]).indexOf(obj[prop]) === pos;
    });
}


console.log(removeDuplicates(response,['id','value'])); // specify either 'id' or 'value' for the second parameter.

Answer №2

My solution seems promising

for(let item of response) {
    if(!this.listData.find((ldata) => item.value.substring(item.value.lastIndexOf('_')+1) === ldata.time)) {
        let tempVal = {id: '', time: ''};
        let val = item.value.split('_')
        if (val.length==2) {
            if(val[val.length-1].length==2) {
                tempVal.id = val[0];
                tempVal.time = val[1];
            }
            this.listData.push(tempVal);
        }
    }
}

Answer №3

To achieve an optimal solution (loop only once i.e. O(n)), use object property to check if the property has already been added. This way, you can avoid looping to find out if the property has already been added.

Here is a sample solution:

let response = [{
    "id": "0DRDCH03DR51GGJGJNP80F7XZ8",
    "value": "36af1784bec4_566601260"
  }, {
    "id": "0DRDCH03DR51GGJGJNP80F7XZ8",
    "value": "36af1784bec4_566601260"
  }, {
    "id": "0DRDCFYGM2CAHAXYK96BPT9RHV",
    "value": "36af1784bec4_566601140"
  }],
  listData = [],
  tempObj = {};
for (let data of response) {
    let value = data.value.split('_');
  if (!tempObj.hasOwnProperty(value[1])) {
    tempObj[data.value[1]] = "";
    listData.push({
      id: value[0],
      time: value[1]
    });
  }
}

console.log(listData);

Update: As per feedback, now checking only for duplicate time values

Answer №4

You can achieve the same result by converting objects to strings using JSON.stringify as shown below :

let response = [{
  "id": "0DRDCH03DR51GGJGJNP80F7XZ8",
  "value": "36af1784bec4_566601260"
}, {
  "id": "0DRDCFYGM2CAHAXYK96BPT9RHV",
  "value": "36af1784bec4_566601140"
}, {
  "id": "0DRDCH03DR51GGJGJNP80F7XZ8",
  "value": "36af1784bec4_566601260"
}];

let o = response.reduce((acc, cv) => {
  if (!acc[JSON.stringify(cv)]) {
    acc[JSON.stringify(cv)] = true; //something non-falsy
  }
  return acc;
}, {});

let res = Object.keys(o).map(x => JSON.parse(x));
console.log(res);

Edit As user3297291 mentioned

It is important to note that JSON.stringify({ a: 1, b: 2}) !== JSON.stringify({ b: 2, a: 1 })

Hence, the above approach may not work in such cases.

A more efficient solution would be

let response = [{
  "id": "0DRDCH03DR51GGJGJNP80F7XZ8",
  "value": "36af1784bec4_566601260"
}, {
  "id": "0DRDCFYGM2CAHAXYK96BPT9RHV",
  "value": "36af1784bec4_566601140"
}, {
  "id": "0DRDCH03DR51GGJGJNP80F7XZ8",
  "value": "36af1784bec4_566601260"
}];

let o = response.reduce((acc, cv) => {
  if (!acc[cv.value]) {
    acc[cv.value] = true; //something non-falsy
  }
  return acc;
}, {});

let res = Object.keys(o).map(x => {
  let t = x.split('_');
  return {
    id: t[0],
    time: t[1]
  };
});
console.log(res);

Answer №5

To achieve this task, you can utilize a map function to gather the ids and then apply a filter function to eliminate duplicates:

const response = [{"id":"0DRDCH03DR51GGJGJNP80F7XZ8","value":"36af1784bec4_566601260"},{"id":"0DRDCFYGM2CAHAXYK96BPT9RHV","value":"36af1784bec4_566601140"}];

const ids = response.map(item => item.value.split('_')[0]).filter((item, index, array) => index === array.indexOf(item));

console.log(ids);

Alternatively, you can also use a reduce function:

const response= [{"id":"0DRDCH03DR51GGJGJNP80F7XZ8","value":"36af1784bec4_566601260"},{"id":"0DRDCFYGM2CAHAXYK96BPT9RHV","value":"36af1784bec4_566601140"}];

const ids = response.reduce((accumulator, currentItem) => {
  const id = currentItem.value.split('_')[0];
  return accumulator.includes(id) ? accumulator : [...accumulator, id];
}, []);

console.log(ids);

Answer №6

Recent versions of JavaScript now support relying on the consistency of object structure. This means we can use stringification and comparison of two strings to produce accurate results:

JSON.stringify({id:0, name:foo}) === JSON.stringify({id:0, name:foo}) // true

When dealing with an array of objects:

  1. Stringifying an object for testing
  2. Iterating through a collection of objects and stringifying each one
  3. Comparing the two strings created

This approach is beneficial as it eliminates the need to know specific key names, working effectively with any type of object...

arr = [{object}, {object2}, {etc...}]
test = JSON.stringify(obj);

for ( let i = 0, j = arr.length; i < j; i++ ) {
  let testAgainst = JSON.stringify(arr[i]);
  if (test === testAgainst) { 
    console.log('matches');
  } else {
    console.log('no match');
  }
}

By comparing two strings, you can easily identify matches. Feel free to leave a comment if there are any additional aspects to consider.

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

Converting a dynamic JSON object into a generic type in TypeScript

I need assistance with converting a JSON object into the equivalent generic type in TypeScript. The JSON object I have contains dynamic keys such as applications and permissions. The keys inside applications, like application_management and user_managemen ...

Creating a List with Sublists that are displayed when hovering over the parent List is a key element of effective design

Hovering over 'View Rows' should open up both New Records and Old Records <div> <li>Add Rows</li> <li>DeleteRows</li> <li>View Rows <ul> <li>View New Records</li ...

I am trying to retrieve the class name of each iframe from within the iframe itself, as each iframe has a unique class name

My index HTML file contains multiple Iframes. I am trying to retrieve the class names of all iframes from inside an iframe. Each iframe has a different class name. If any of the iframes have a class name of 'xyz', I need to trigger a function. I ...

Tips for validating a string in a URL with Selenium IDE

When I click on a tab on my website, it triggers an AJAX service call where the URL contains parameters related to the data being loaded after the tab is clicked. The data is displayed as horizontal tiles one below the other, with 4 tiles being loaded pe ...

Setting up GameClosure on a Windows machine

Is it possible to install GameClosure on Windows? The installation guide mentions that only OSX is officially supported, but there have been reports of success running it on Linux and Windows. However, the process for doing this is not well-documented. A ...

Having trouble retrieving POST data with the Webextensions API

Looking to retrieve POST data using a Webextensions API on page load. Implemented a background script with the code below: browser.webRequest.onBeforeSendHeaders.addListener( getPostData, { urls: ['<all_urls>'], types: ["main_fr ...

Toggle visibility of div based on current business hours, incorporating UTC time

UPDATE I have included a working JSFiddle link, although it appears to not be functioning correctly. https://jsfiddle.net/bill9000/yadk6sja/2/ original question: The code I currently have is designed to show/hide a div based on business hours. Is there a ...

Strategies for Implementing Pagination in an Angular 2 HTML Table Without the Use of Third-Party Tools

I have an HTML table that displays basic details along with images. I am looking to implement pagination for this table in Angular 2. Are there any alternatives to using ng2-pagination? ...

How to incorporate sound files in JavaScript

I have a collection of small audio files that I want to play sequentially, not all at once. To do this, I am using the Audio object in JavaScript as shown below: var audio_1 = new Audio(); var audio_2 = new Audio(); var audio_3 = new Audio(); audio_1.src ...

Error message: "The property or method you are trying to access is not defined

I had no issues with my app until I added the JavaScript, now I'm getting constant errors in the console. One of the errors I see is: Property or method "show" is not defined on the instance but referenced during render. Make sure that this proper ...

Deselect the checkbox if you are checking a different checkbox

Struggling with my code, it's hit or miss. Feeling defeated. Seeking assistance to uncheck a checkbox when another checkbox is checked. Check out the code below: JavaScript: $("#1 #checkAll").change(function() { if ($("#1 #checkAll").is(' ...

StealJS Module Repathing Techniques

There seems to be an issue with my setup, so I welcome all inquiries. I am utilizing an npm package called xrm-mock for a MS CRM mocking framework. Here is how I have configured it: steal.config({ meta: { "dependencyModule": { deps ...

The typings for object properties in Typescript

I recently encountered a function call in my code: var myVar = myFunction({ property: 'prop', functionProperty() { console.log(this.property); }, functionProperty2() { this.functionProperty(); } }); I' ...

Is there a way for me to determine if there are any related projected materials available?

I am working with two components that need to be projected. <app-form-field> <component-one/> <component-two/> </app-form-field> If I want to determine if component one is projected inside app-form-field, I can do the followi ...

Find the total of values in an array that may be null or undefined

In this scenario, I have an array that looks like this: myData = [[2, null, null, 12, 2], [0, 0, 10, 1, null], undefined]; The goal is to calculate the sum of each sub-array, resulting in an array like this: result = [16, 11, 0]. The ...

"Automate the process of manual content duplication with JavaScript's for each replacement

Seeking a solution to automate the selection process without writing individual JS scripts for every input. For instance, having 10 double inputs (total of 20 inputs) and utilizing the each() function or other methods by only declaring selectors. Find th ...

Expanding Arrays in TypeScript for a particular type

There is a method to extend arrays for any type: declare global { interface Array<T> { remove(elem: T): Array<T>; } } if (!Array.prototype.remove) { Array.prototype.remove = function<T>(this: T[], elem: T): T[] { return thi ...

A step-by-step guide on incorporating box-shadow for the jackColor in the Switchery Plugin

I am looking to add a box shadow to my iOS7 style switches for checkboxes when they are checked. Here is the code I have so far: var elems = Array.prototype.slice.call(document.querySelectorAll('.js-switch')); elems.forEach(function (html) { va ...

Accessing external data in Angular outside of a subscription method for an observable

I am struggling to access data outside of my method using .subscribe This is the Service code that is functioning correctly: getSessionTracker(): Observable<ISessionTracker[]> { return this.http.get(this._url) .map((res: Response) => ...