Identifying the initial object with a duplicate property within an array of objects using JavaScript

In my code, I have an array structured like this:

 var myArray = [
    {id: 1, entry_id: 1, name: 'test', email: 'email1'},
    {id: 2, entry_id: 1, name: 'test', email: 'email2'},
    {id: 3, entry_id: 2, name: 'test', email: 'email3'},
    {id: 4, entry_id: 2, name: 'test', email: 'email4'},
    {id: 5, entry_id: 3, name: 'test', email: 'email5'},
    {id: 6, entry_id: 3, name: 'test', email: 'email6'},
    {id: 7, entry_id: 3, name: 'test', email: 'email7'},
 ];

The objective is to identify the first element within each group sharing the same 'entry_id' and 'name' properties. The expected result should be:

 [
    {id: 1, entry_id: 1, name: 'test', email: 'email1', isFirst:true},
    {id: 2, entry_id: 1, name: 'test', email: 'email2', isFirst:false},
    {id: 3, entry_id: 2, name: 'test', email: 'email3', isFirst:true},
    {id: 4, entry_id: 2, name: 'test', email: 'email4', isFirst:false},
    {id: 5, entry_id: 3, name: 'test', email: 'email5', isFirst:true},
    {id: 6, entry_id: 3, name: 'test', email: 'email6', isFirst:false},
    {id: 7, entry_id: 3, name: 'test', email: 'email7', isFirst:false},
 ];

My attempt involved iterating through the array and setting the 'isFirst' value accordingly, resulting in the following output:

 [
    {id: 1, entry_id: 1, name: 'test', email: 'email1', isFirst:true},
    {id: 2, entry_id: 1, name: 'test', email: 'email2', isFirst:false},
    {id: 3, entry_id: 2, name: 'test', email: 'email3', isFirst:true},
    {id: 4, entry_id: 2, name: 'test', email: 'email4', isFirst:false},
    {id: 5, entry_id: 3, name: 'test', email: 'email5', isFirst:true},
    {id: 6, entry_id: 3, name: 'test', email: 'email6', isFirst:false},
    {id: 7, entry_id: 3, name: 'test', email: 'email7', isFirst:false},
 ];

Is there a more efficient approach to achieving this without using nested loops?

Your insights are greatly appreciated!

For additional reference, here is the link to the code on jsfiddle: https://jsfiddle.net/88p5p5oj/30/

Answer №1

If you're looking to efficiently gather the initial flags of a desired group, consider utilizing a hash table within a single iteration.

var data = [{ id: 1, entry_id: 1, name: 'test', email: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="ccaaa3a38caeadbee2afa3a1">[email protected]</a>' }, { id: 2, entry_id: 1, name: 'test', email: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="91f3f0e3d1f7fefebff2fefc">[email protected]</a>' }, { id: 3, entry_id: 2, name: 'test', email: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="b7d1d8d8f7d5d6c599d4d8da">[email protected]</a>' }, { id: 4, entry_id: 2, name: 'test', email: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="d5b7b4a795b3babafbb6bab8">[email protected]</a>' }, { id: 5, entry_id: 3, name: 'test', email: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="573d38321738343236397934383a">[email protected]</a>' }, { id: 6, entry_id: 3, name: 'test', email: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="dbbdb4b49bb9baa9f5b8b4b6">[email protected]</a>' }, { id: 7, entry_id: 3, name: 'test', email: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="f3959c9cb3919281dd909c9e">[email protected]</a>' }],
    identifiers = ['entry_id', 'name'],
    hashTable = Object.create(null);

data.forEach(item => {
    var key = identifiers.map(id => item[id]).join('|');
    item.isFirst = !hashTable[key];
    hashTable[key] = true;
});

console.log(data);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Answer №2

Make sure to return the myArray once the first match is found and set. Alternatively, you can return the index of the array where the match is found and use that for further actions.

If you want the isFirst property to be added to each object within the loop, modify your code as follows:

function updateArray() {
    var foundFirst = false;
    myArray.forEach((item, i) => {
      item.isFirst = false;
      myArray.forEach((item2, j) =>{
        if (!foundFirst && item.entry_id == item2.entry_id && item.name == item2.name && i < j ) {
          item.isFirst = true;
          foundFirst = true;
        } else {
          item.isFirst = false;
      }
   })
 })
 return myArray;
}

Answer №3

Using an object named visited helps keep track of the elements that have already been checked.

In this scenario, there are two objects identified as 'Jenny Block'

var myArray = [    {id: 1, entry_id: 1, name: 'test', email: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="17717878577576653974787a">[email protected]</a>'},    {id: 2, entry_id: 1, name: 'test', email: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="7f1d1e0d3f191010511c1012">[email protected]</a>'},    {id: 3, entry_id: 2, name: 'test', email: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="f89e97...  

visited = {};
   
myArray.forEach(c =>  {
  var key = `${c.entry_id}|${c.name}`;
  c.isFirst = !visited[key];
  visited[key] = true
});
console.log(myArray);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Answer №4

To iterate through an array, you can utilize the Array.map() method along with a helper object. The process involves setting the isFirst property to false for each element in the array. If the element is not already present in the helper object, it is added, and the value of isFirst is set to true.

To create a copy of the original object, you can use object spread or Object.assign(), and include the isFirst property.

const myArray = [
  {id: 1, entry_id: 1, name: 'test', email: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="24424b4b644645560a474b49">[email protected]</a>'},
  {id: 2, entry_id: 1, name: 'test', email: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="0260637042646d6d2c616d6f">[email protected]</a>'},
  {id: 3, entry_id: 2, name: 'test', email: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="86e0e9e9c6e4e7f4a8e5e9eb">[email protected]</a>'},
  {id: 4, entry_id: 2, name: 'test', email: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="5b393a291b3d343475383436">[email protected]</a>'},
  {id: 5, entry_id: 3, name: 'Joe Ocean', email: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="d7bdb8b297b8b4b2b6b9f9b4b8ba">[email protected]</a>'},
  {id: 6, entry_id: 3, name: 'Jenny Block', email: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="b0d6dfdff0d2d1c29ed3dfdd">[email protected]</a>'},
  {id: 7, entry_id: 3, name: 'Jenny Block', email: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="3d5b52527d5f5c4f135e5250">[email protected]</a>'},
];

const helper = Object.create(null);
const result = myArray.map(function(o) {
  const key = `${o.entry_id}-${o.name}`;
  const isFirst = helper[key] ? false : (helper[key] = true);

  return { ...o,  isFirst };
});

console.log(result);

Answer №5

Consider revising your function to something like this.. Keep in mind that this assumes your json is ordered.

const myArray = [
  {id: 1, entry_id: 1, name: 'test', email: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="ccaaa3a38caeadbee2afa3a1">[email protected]</a>'},
  {id: 2, entry_id: 1, name: 'test', email: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="37555645775158581954585a">[email protected]</a>'},
  {id: 3, entry_id: 2, name: 'test', email: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="bddbd2d2fddfdccf93ded2d0">[email protected]</a>'},
  {id: 4, entry_id: 2, name: 'test', email: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="9af8fbe8dafcf5f5b4f9f5f7">[email protected]</a>'},
  {id: 5, entry_id: 3, name: 'Joe Ocean', email: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="e3898c86a38c8086828dcd808c8e">[email protected]</a>'},
  {id: 6, entry_id: 3, name: 'Jenny Block', email: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="9afcf5f5daf8fbe8b4f9f5f7">[email protected]</a>'},
  {id: 7, entry_id: 3, name: 'Jenny Block', email: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="6d0b02022d0f0c1f430e0200">[email protected]</a>'},
];

function updateArray() {
  var prevItem = "";
  myArray.forEach((item, i) => {
       item.isFirst = item.entry_id != prevItem;
       prevItem = item.entry_id;
  });
  return myArray;
}

console.log(updateArray());

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

Tips for effectively passing a $scope object between various controllers

I am encountering an issue with sharing a $scope object between two controllers. Within the 'IssueBookCtrl' controller, I update the 'books' object element value like this: $scope.books[i].issued = true; After that, I use the $emit s ...

What is the best way to perform a keyword search in AngularJS?

My data consists of code:description pairs (e.g. cmsc100: Web Programming). I have a search box where users can enter either the code or description. Upon clicking the button, the program should display the data that matches the entered code/description or ...

The function you are trying to execute in jQuery Mobile is not defined

I'm currently working on creating an external panel, but I've encountered some difficulties. Below is the HTML code: <html> <head> <title>My Page</title> <meta name="viewport" content="width=devi ...

Can you indicate a specific version of an npm module without making changes to the package.json file?

I am looking to update the version of a npm module without making changes to the package.json file. I want to avoid forking the repository if possible. If the package.json appears similar to this: ... "dependencies": { "iwan ...

What causes the result of UNDEFINED when accessing an ENVIRONMENT VARIABLE in a REACT application?

Unfortunately, I've hit a roadblock with this seemingly simple question and can't seem to find the answer. I'm having trouble accessing environment variables in a specific file. I am using create-react-app (^16.11.0) The .env file is loca ...

Modifying button text dynamically during save operation with AngularJS

Is it possible to dynamically change the text on a submit button while data is being saved in a form? Here's an example of the button: <button ng-click="save()">Save data</button> I have updated my save function based on some suggestion ...

Utilizing Webpack to Import GLB Models into Three.js

Just delving into the world of Webpack for the first time and I'm encountering some difficulties when trying to add my glb model. The model itself is fine, it's been used multiple times and I placed it in the public folder. I'm puzzled by th ...

What is the optimal method for transmitting data for a substantially large music playlist via HTTP?

I am currently in the process of developing an online music player. My main challenge lies in retrieving a comprehensive list of songs from the database and transmitting it to the user. The user should have the ability to create playlists on-the-go, hence ...

Is it possible to enable auto play on HTML5 Video for iPad similar to BBC iPlayer?

Can HTML5 Videos automatically play on iPads? I used to believe that it wasn't possible because of iOS restrictions, but after trying BBC iPlayer on my iPad, I noticed that the videos did autoplay upon loading. Could this indicate that it is indeed ...

The error message java.lang.NumberFormatException: Unable to parse the input string: "2017-01-28 13:28:20" occurred

During the execution of my java project, I encountered an error with a Gson deserializer function. The error message states: java.lang.NumberFormatException: For input string: "2017-01-28 13:28:20" at java.lang.NumberFormatException.forInputString(NumberF ...

Utilize a select box to toggle between enabling and disabling options

Could someone please help me with enabling and disabling a text field based on a select box option? I'm not sure if I have written the code correctly below. If there are any errors, please correct me. <body> <table width="500" border="1"> ...

Master the art of transforming Json data into a structured associative array

I am facing an issue with handling JSON data that was posted from a form and unable to process it or store it in a database. This is what the posted data looks like: Array ( [apd0] => [{"ratio":"1","size":"S","quantity":"83"},{"ratio":"2","size":"M ...

Why does the <div> element still have an offset even though its width and height are set to 100px and padding, margin, and border are set to 0px?

After styling my div element with specific CSS rules, I'm encountering an issue. The div has a set width and height of 100px along with padding, border, and margin all set to 0px. However, the elements are not being offset from the edges of the browse ...

The SVG format quickly displays new and larger datasets on line charts without any transition effects

My goal is to create a line chart with animated transitions similar to this demo, but without the dots. I am attempting to integrate this functionality into a react component where the update method can be triggered by another component, allowing the d3 op ...

ngSwitchCase provider not found

While following a tutorial and trying to implement what I learned, I encountered an error that I'm having trouble understanding. The browser console shows an error message stating [ERROR ->]<span *ngSwitchCase="true">, but I can't figure ...

Struggling with making react-hook-form correctly validate an email address

I've been struggling for a long time to make this validation work correctly, but it seems impossible. I even added some text at the bottom to display an error message related to the email, but it always shows no error, regardless of the situation. Ed ...

Tips for adding content to a textarea after making manual changes to its existing content

One issue I encountered is with capturing the enter key on an input field and appending it to a textarea. While this works initially, any edits made directly on the textarea seem to disrupt the functionality. How can this be resolved? I have tested this i ...

Visualizing JSON data in React.js using Chart.js

Currently, as a beginner in ReactJS, I am working on an application that displays COVID-19 data from a JSON API in a visual format using Chart.js. However, despite trying various solutions, I am unable to visualize the data. Below is my source code: App ...

Unable to execute node file in Visual Studio Code's terminal

My attempt to run a file using the terminal in Visual Studio Code has hit a snag. Despite my best efforts, I keep encountering an error message that reads as follows: For example, when I type "node myfile.js" into the terminal, I get the following error: ...

Exploring JSON data in AngularJS

After creating a new Angular App, I decided to store some data in a JSON file. My main concerns are where to best store the .json file within the app and how to access it. Currently, I am facing this error in my Chrome console: GET http://localhost:8000/t ...