Merging sort and uniq functionalities to create a single function in JavaScript

I've been working with the sortBy and uniqBy functions, but I find myself iterating over the array twice when using the combined sortUniqBy. If you want to check out the code, feel free to click on this link to the codesandbox. Here's a snippet of the code:


export const sortBy = <T>(o: T[], selector: (item: T) => any): T[] => {
  const result = o.slice(0);

  result.sort((x, y) => {
    const a = selector(x);
    const b = selector(y);

    return a > b ? 1 : a < b ? -1 : 0;
  });

  return result;
};

export const uniqBy = <T>(o: T[], selector: (item: T) => any): T[] => {
  const ret: T[] = [];

  const set = new Set<T>();

  o.forEach((s) => {
    const value = selector(s);

    if (set.has(value) === false) {
      set.add(value);
      ret.push(s);
    }
  });

  return ret;
};

export const sortedUniqBy = <T>(o: T[], selector: (item: T) => any): T[] => {
  return uniqBy(sortBy(o, selector), selector);
};

sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor); // [1.1, 2.3]

My question is, is there a way to efficiently sort and remove duplicates in a single loop instead of running two separate loops?

Answer №1

One creative way to utilize an object as a hash table is by organizing index-like keys in order and extracting corresponding values from it.

function sortedUniqBy(array, callback) {
    const items = {};
    for (const value of array) {
        const temp = callback(value);
        if (!(temp in items) || items[temp] > value) items[temp] = value;
    }
    return Object.values(items);
}

console.log(sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor)); // [1.1, 2.3]

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

Extracting the "defined" type from a TypeScript property during runtime

My current task Presently, I am iterating through the keys of an object and transferring their values to another object. interface From { [key: string]: string; } let from: From = { prop1: "foo", prop2: "23", }; interface To { [key: str ...

Generating images using Node.js and GraphicsMagick

I'm looking for a way to generate an image using graphicsMagick and node.js. Typically, I can achieve this with the following command: gm convert -background transparent -pointsize 30 -gravity Center label:türkçee HEEEEEY.png But I need to replic ...

What are the steps to view my HTML webpage on a smartphone?

Recently, I successfully created an HTML webpage with CSS and JS that looks and functions perfectly on my PC. However, when attempting to access it on my phone, I encountered some issues. Despite transferring all the necessary files to my phone, only the ...

Troubleshooting the issue with generateStaticParams() in NextJs/TypeScript

My NextJs app has a products page that should render dynamic routes statically using generateStaticParams(). However, this functionality does not work as expected. When I run "npm run build," it only generates 3 static pages instead of the expected number. ...

The synchronization issue between ng-class and animation

I'm experiencing a strange issue with ng-class and suspect that it may be related to a race condition. Here is the example on Plunker: example Below is the relevant JavaScript code: self.slideLeft = function() { if (self.end_index < se ...

Checkbox click event not triggering properly

I am facing challenges in triggering an onclick event for the "Elevation" checkboxes located at the URL provided above. <input type="checkbox" value="A" id="elevation_A" onclick="changeElevation(this.value);" /> For some reason, the "changeElevati ...

How is it that connecting an event listener to a React child component can be done in a way that resembles simply passing a prop

class Board extends React.Component { constructor(props) { super(props); this.state = { squares: Array(9).fill(null), }; } handleClick(i) { // do things } render() { return ( <div ...

There seems to be a problem retrieving the JSON file

My JavaScript file is designed to fetch a JSON file and execute a function if successful. If there's an error, it should display an alert window with the message "error". However, despite checking the syntax, I keep receiving an error alert every time ...

Tips for creating code that continues to run in the "background" endlessly

I am facing the challenge of working with an API that has a limited request capacity, and I want to avoid exceeding this limit by having users directly access the endpoint. My solution involves using JavaScript to automate periodic requests to the API, whi ...

What is the best way to showcase images using Vue.js?

For my Vue project, I am encountering issues with the image paths not working properly. Despite trying different variations, such as: <figure class="workout-image"> <img :src= "images.bicep" width= "200px" ...

Utilizing ES6 Map type in TypeScript for Angular 2 Response Data Transfer Object Definition

Is it possible to utilize the es6 Map type in an HTTP Response DTO? Let's consider an Angular 2 request: public loadFoos(): Observable<FoosWrapper> { return this.http.get("/api/foo") .map(res => res.json()); } Now, take a loo ...

Error encountered: iPad3 running on iOS7 has exceeded the localStorage quota, leading to a

Experiencing a puzzling issue that even Google can't seem to solve. I keep getting the QuotaExceededError: DOM Exception 22 on my iPad3 running iOS7.0.4 with Safari 9537.53 (version 7, WebKit 537.51.1). Despite turning off private browsing and trying ...

Transferring an IONIC project to a different computer

Let me outline the current situation I am facing - I primarily work as a firmware developer rather than a software developer. Recently, a team member who was responsible for developing the front end of an application in IONIC has left the company, leaving ...

Obtain the data from a nested array

I'm facing a situation where I have the following code: var obj = { level1 : { level2 : 'value' } }; I also have another object: var returnData = { value: "level1.level2", anotherThing: "level1" }; The goal is to ...

What is the best way to change the response URL in an AJAX function?

I have a function using ajax that redirects to the response from a specified URL upon success: document.getElementById("button1").addEventListener("click", function (e) { e.preventDefault(); $.ajax({ url: 'http://localhost:8080/someLo ...

Generating a JavaScript object based on an array of keys

I'm currently grappling with a task that is proving to be quite challenging. I have a set of arrays structured like this: ['key1', 'key2', 'key3'] ['key1', 'key2', 'key4'] ['key1', ...

Ways to reach state / methods outside of a React component

Implementing the strategy design pattern to dynamically change how mouse events are handled in a react component is my current task. Here's what my component looks like: class PathfindingVisualizer extends React.Component { constructor(props) { ...

While working with AJAX, the variable value remains static and is not refreshed

My jQuery code successfully calls a REST Service and handles the response in the AJAX Success event. However, I'm facing an issue where the variable "SelectedVal" (document.getElementById('Text1').value) is not getting updated with each cli ...

The error message TS2322 in MUI v5 states that the property 'fullWidth' is not found in the type 'IntrinsicAttributes & { theme: Theme; } & { children?: ReactNode; }'

As a user of MUI v5, I have implemented a straightforward FormControl as seen below. It is important to note that the property fullWidth is supported according to the official documentation. import React, { PropsWithChildren } from 'react' import ...

Background Patterns on Webpages

My website has a lovely gradient background on the html tag in css, while the body tag showcases a seamless pattern repeating on both the x and y axes. Everything was looking great until I checked the website on an iPad/iPhone in portrait mode, where the ...