Eliminate repeated elements from an array of objects using Typescript

Recently, I stumbled upon an API that provides a list of countries and their corresponding cities. You can check out the API here.

Upon fetching the data, I noticed there were duplicate entries for some cities within the same country. Here's an example from the response:

     {
        "country": "United States",
        "cities": [
            "Abbeville",
            "Abbeville",
            "Abbeville",
            "Abbeville",
            "Abbeville",
            "Abbotsford",
       ],
      },

To clean up these duplicates, I wrote a function which does the job, but it feels a bit clunky. Here is my code snippet:

    getCountries = async () => {
    if(!this.mounted) return;

    interface typeData {
        data: Array<{country: string, cities: Array<string>}>;
        error: boolean;
        msg: string;
    }
    const result: typeData = await this.data.GetCountries();

    let findDuplicates = result.data.map(i => {
        let currentCountry = i.country;
        let currentCities: Array<string> = [];
        i.cities.filter(c => {
            if(!currentCities.includes(c)) currentCities.push(c);
        });
        let finalArray: Array<{country: string, cities: Array<string>}> = [{
            country: currentCountry,
            cities: currentCities
        }];
        return finalArray;
    }).reduce((sofar, current) => [...sofar, ...current], []);
    findDuplicates && this.setState({data: {weather: this.state.data?.weather, countries: findDuplicates}})
}

I'm wondering if there is a more efficient way to achieve this task using a one-liner with methods like reduce, map or filter. The examples I found so far don't quite match the structure of my data:

Array<{country: string, cities: Array<string>}>.

Answer №1

One way to eliminate duplicates is by using the Set function:

let data = {
  "country": "United States",
  "cities": [
    "Abbeville",
    "Abbeville",
    "Abbeville",
    "Abbeville",
    "Abbeville",
    "Abbotsford",
  ],
};

data.cities = [...new Set(data.cities)];

console.log(data.cities);
      
      

Answer №2

Have a look at this question: How to Remove duplicate values from JavaScript array

Alternatively, you can also consider the following code snippet:

 let data={
        "country": "United States",
        "cities": [
            "Abbeville",
            "Abbeville",
            "Abbeville",
            "Abbeville",
            "Abbeville",
            "Abbotsford",
       ],
      }
      let obj={}
      data.cities.forEach((x)=>obj[x]=x)
      let newArr=Object.keys(obj)
      console.log(newArr)

Answer №3

To efficiently remove duplicates, you can utilize a combination of Array.filter and Array.findIndex. This method may not be the most performant but gets the job done.

const data = [
    {
        "country": "United States",
        "cities": [
            "Abbeville",
            "Abbeville",
            "Abbeville",
            "Abbeville",
            "Abbeville",
            "Abbotsford",
       ],
    },
    {
        "country": "United States",
        "cities": [
            "Abbeville",
            "Abbeville",
            "Abbeville",
            "Abbeville",
            "Abbeville",
            "Abbotsford",
       ],
    }
]

type IsDuplicate<T> = (a: T, b: T) => boolean

const removeDuplicate = <TItems> (collection: TItems[], isDuplicate: IsDuplicate<TItems>) => 
    collection.filter((item, index, items: TItems[]) => 
        items.findIndex(secondItem => isDuplicate(item, secondItem)) === index)

console.log(removeDuplicate(data, (a, b) => a.country === b.country))

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

What is the best way to spin an element around its center?

I'm faced with a challenge where I have an element that needs to be rotated using JavaScript. The rotation is currently functional, but it's rotating around points other than its center. My goal is to rotate the element around its own center. ...

Structure of Sequelize calls

Recently, I've been working with sequelize and attempting to query my database with the code below: models.user.findOne({ where: {email: req.body.email} }, (err, existingUser) => { .... More code } Unfortunately, the code block isn't executi ...

Why is my formArray in Angular not validating or updating correctly?

I'm struggling to implement validation and updating for an array of form fields within my parent form group. Can anyone provide insight on what I might be missing? My goal is to add a new 'Vendor Line' with multiple form fields and validate ...

Using React's useState with WebSocket is causing the array to fail to update properly

Greetings, I am currently working on integrating WebSockets with react, and possibly electron as well. When the connection opens, the message 'Connection opened' is correctly added to the beginning of a new array and displayed as expected. Howe ...

Understanding the concept of a "class variable" in Typescript when referring to a variable that belongs to another class

When we declare a variable at the class level and assign it the type of another class, such as in the following code: let greeter: Greeter; //line 1 greeter = new Greeter("world"); What is contained within 'greeter' on line 1? ...

How can jQuery Sortable Connect Lists help store values within list items?

Currently, I am exploring the demonstration for sorting items at this link. However, I am facing a challenge where I want the text in the list to appear a certain way, but when I save the data on the server side, I need to use values instead. Since the < ...

What is the process for removing a particular file from my bundle?

I am currently utilizing webpack to build my angular2/typescript application and have successfully generated two files, one for my code and another for vendors. However, I am in need of a third file to separate my config (specifically for API_ENDPOINT) whi ...

I require Ajax .on to trigger during the second .on event, rather than the first one

I'm facing a challenge with implementing chained selects that trigger my ajax call on change. The issue arises when the Chained Select populates the second select prematurely causing the ajax call to fire unexpectedly. Is it feasible to bypass the in ...

I am unable to access the environment file variable values within my Node project

I'm facing an issue with accessing 2 variables in my env file for Port and MongoDB link. Despite trying various solutions from the internet, I am unable to retrieve these values in both the listen method and database connection. Below is a snippet of ...

Incorporate dots into every slide using the React Slick slider

When implementing a slider in React.js, I use React Slick. The API provided by React Slick allows us to easily incorporate previous and next buttons on each slide using the Previous and Next methods. However, I am curious about how to achieve the same fun ...

What causes getBoundingClientRect() in Javascript to occasionally produce decimal values?

Currently, I am experimenting with an HTML5 canvas element. A major concern of mine is setting up a mousemove event to monitor the movement of the mouse over the canvas for drawing and other purposes. Unfortunately, I have not been able to locate a definit ...

"Enhancing User Experience with Animated Progress Bars in Three.js

Is there a way to create a progress bar animation in three.js? I've been grappling with this issue for quite some time now. I attempted to replicate the html5 video player progress bar method, but unfortunately, it doesn't seem to be compatible w ...

Order of AngularJS Scope.on and Scope.emit Invocation in a Filter

One of the challenges I am facing involves watching a value in one controller that is changed in another controller within my filters. The goal is to determine whether an emit should be triggered based on the updated value. Here's the current situatio ...

Allowing server to reboot following a crash

I typically rely on my process manager to restart my app in the event of a crash. However, recently I came across error handling in Express: app.use( (err,req,res,next) => { console.log(err.stack); res.status(500).send({"Error" : err.stack}); }); ...

What is the best way to combine JavaScript objects with identical values?

We have a task to compare each input key with others to find any common values. If there are common values, we need to concatenate them together and display the pairs. If no common values are found, then an empty array should be displayed as output. inpu ...

Data is not loaded until after the HTML for the Nuxt page has been

My issue is that I have a dynamic page where product details are loaded, but the html code loads before the data. This results in errors when trying to use static elements like images because the "product" object does not exist. To address this problem, I ...

Navigating Through Radio Questions with a Back Button Using Javascript

Having trouble looping through an array of objects with 'back' and 'next' buttons? It seems that the loop is not functioning correctly. The aim is for the 'back' button to decrement based on the number of times the 'next& ...

What is the best way to dynamically incorporate Before After CSS code in Vue?

I am facing a unique challenge in my current project. I need to dynamically apply colors from data inside a v-for loop, specifically for the :after CSS pseudo-element. While normal CSS properties are easily applicable, I am struggling with applying styles ...

Tips for Maintaining User Data Across Pages in React using React-Router-Dom and Context

I've been tackling the login functionality of a client-side application. Utilizing React alongside TypeScript, I've incorporated react-router-dom and Context to manage the user's data when they log in. However, upon refreshing the page, the ...

What measures can I take to restrict users from adding names that are already in the system?

In the handleSubmit() function, I am attempting to prevent the user from adding an existing user, but it doesn't seem to be functioning properly. Ideally, if the name being added already exists in the persons list, an alert should be triggered. EDIT: ...