What is the most efficient way to identify the top n instances of a specific value within an array using Typescript or JavaScript?

Working with TypeScript, I am dealing with an array of objects that may contain the same values as other objects within the array. For example, the following array consists of objects with the value "intent". My goal is to identify the top 3 most commonly occurring intents:

[
  {
    "intent": "hello",
    "other_value": "blah"
  },
  {
    "intent": "hello",
    "other_value": "blahblah"
  },
  {
    "intent": "hi",
    "other_value": "anothervalue"
  },
  {
    "intent": "hello",
    "other_value": "what?"
  },
  {
    "intent": "hello",
    "other_value": "eh?"
  },
  {
    "intent": "hi",
    "other_value": "okthen"
  },
  {
    "intent": "yo",
    "other_value": "alright"
  },
  {
    "intent": "hi",
    "other_value": "yes"
  },
  {
    "intent": "yo",
    "other_value":"yawhat?"
  },
  {
    "intent": "hey",
    "other_value": "meh"
  }
]

I am looking for a solution that provides me with a clear output showing the top 3 intents, such as a key/value pair array:

[
  {
    "intent": "hello",
    "occurrences": 4
  },
  {
    "intent": "hi",
    "occurrences": 3
  },
  {
    "intent": "yo",
    "occurrences": 2
  }
]

Below is my attempt at solving this issue:

function top3(array) {
    let results = [];
    array.forEach(item => {
        if (results[item.intent] != null) {
          results[item.intent] += 1
        } else {
          results[item.intent] = 1;
        }
    });

    results = results.sort();
    return results.slice(0, 3);
}

However, this approach only presents an array of the occurrence values without explicitly stating which intent each value corresponds to. Hence, I am struggling to associate the occurrences with their respective intents.

In attempting to resolve this, I explored various answers shared on resources like Stack Overflow:

Get the element with the highest occurrence in an array

Although I tried implementing the solutions provided, I found it challenging to extend the logic to identify multiple occurrences rather than just the singular highest one. There was uncertainty about how to apply the same principles to find subsequent occurrences beyond the first.

Answer №1

To extract the top three objects with the highest count, start by creating an array of objects, then sort it in descending order based on their occurrences property and finally slice the array to include only the top three elements.

var data = [{ intent: "hello", other_value: "blah" }, { intent: "hello", other_value: "blahblah" }, { intent: "hi", other_value: "anothervalue" }, { intent: "hello", other_value: "what?" }, { intent: "hello", other_value: "eh?" }, { intent: "hi", other_value: "okthen" }, { intent: "yo", other_value: "alright" }, { intent: "hi", other_value: "yes" }, { intent: "yo", other_value: "yawhat?" }, { intent: "hey", other_value: "meh" }],
    count = data
        .reduce((r, { intent }) => {
            r[intent] = r[intent] || { intent, occurences: 0 };
            r[intent].occurences++;
            return r;
        }, {}),
    top3 = Object
        .values(count)
        .sort((a, b) => b.occurences - a.occurences)
        .slice(0, 3);
    
console.log(top3);
console.log(count);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Answer №2

Utilize Array#reduce to generate groups based on a specific criteria:

const data = [{"group":"A","value":"one"},{"group":"B","value":"two"},{"group":"A","value":"three"},{"group":"C","value":"four"}];

const groupedData = data.reduce((acc, item) => {
  if(!acc[item.group]) {
    acc[item.group] = 0;
  }
  
  acc[item.group]++;
  return acc;
}, {});

let topGroups = Object.entries(groupedData).sort((a, b) => b[1] - a[1]).slice(0, 3);

console.log('groups', groupedData);
console.log('top 3', topGroups);

You can then convert the top 3 selection into corresponding objects using Array#map, as shown below:

topGroups.map(item => { [item[0]]: item[1] });

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

Cross-origin resource sharing (CORS) challenge encountered between an Express REST API server and an AngularJS application when running on separate ports

Our application utilizes a decoupled MEAN stack architecture. I am currently facing an issue when attempting to send a request from my Angular frontend to our backend, which is expected to return JSON data. However, each time I send a request from the fron ...

AngularJS function orderBy reverses the array instead of sorting it

I encountered an issue where, after clicking the 'order button', the table does not order as expected. Instead, it reverses all the td elements. For example, 'A', 'C', 'B' becomes 'B', 'C', "A". I ...

Converting a .bmp file to a byte array and storing it in a file using C

While I have searched through similar questions related to this topic, I didn't find them particularly helpful. Although they provided some guidance, I am still somewhat confused. Here is what I am trying to accomplish: We are working with a 132x65 s ...

Identify the moment when the SPAN element reappears in sight

I have a question that may have been asked before, but I haven't found a satisfactory answer yet. Within my HTML code, I have a SPAN element with an onclick event, like so: <span onclick='loadDiv()'>Text</span> When a user cli ...

Manipulate SVG elements by dragging them along the boundary of the path

Looking to achieve a specific functionality where I can drag and drop an element along the edges of a drawn path, rather than inside the path itself. To clarify, the goal is to move the red marked element on the black line bordering the path, allowing move ...

Switching the background color of a button on click and resetting the color of any previously clicked buttons (a total of 8

I'm struggling to implement a feature where only one button out of a column of 8 should be toggled yellow at a time, while the rest remain default green. Unfortunately, I can't seem to get the function to execute on click, as none of the colors a ...

Ways to verify the presence of a key within an array of objects

I'm on a mission to determine whether a specified key exists in an array of objects. If the key value is present, I need to return true; otherwise, false. I enter the key into a text box as input and then attempt to check if it exists in the array of ...

Utilizing Node.js and Jasmine: Preventing the invocation of a Promise function to avoid executing the actual code results in DEFAULT_TIMEOUT_INTERVAL

There is a function below that returns a promise. public async getAverageHeadCount(queryParams: Params, childNode: any, careerTrackId: string): Promise<Metric> { const queryId = this.hierarchyServiceApiUrl + "rolling-forecast/ahc/" + q ...

Tips for extracting key values from an array of objects in Typescript

I am working with an array called studyTypes: const studyTypes = [ { value: "ENG", label: "ENG-RU", }, { value: "RU", label: "RU-ENG", }, ]; Additionally, I have a state variable set ...

What is the proper way to retrieve a specific element within a multidimensional array?

Here is an example of the array structure I am working with: $arr [0] [code]='a code' [number]='a number' [1] [code]='a code' [number]='a number' [2] [code]='a code' ...

Add up the duplicate elements in two arrays

I have dynamically created two arrays with the same number of cells (where array.length is the same, representing a key and value association). Below are the arrays: barData.labels["Food", "Food", "Food", "Food", "Food", "Food", "Food", "Food", "Food", "F ...

Exploring the functionality of a Vue component designed solely through a template

I currently have a basic Vue application set up: <!DOCTYPE html> <html> <head> <meta charset='utf-8'> <meta name='viewport' content='width=device-width, initial-scale=1, shrink-to-fit=no'& ...

An issue has occurred: Unable to access information of unknown origin (reading 'admin')

Hey there, I am encountering an issue when attempting to restructure my project as MVC. I am implementing use cases in my models with the goal of organizing my structure like this: When a route is accessed, it goes to the controller and then the controller ...

When using a Vue.js component, the value of this.$route can sometimes come back

I am attempting to retrieve the parameters from the URL and pass them into a method within a Vue component. Despite following advice to use this.$route, I am consistently getting an 'undefined' response. I have tried various solutions suggested ...

Creating HTML elements using JavaScript's Document Object Model

I am trying to create an img tag dynamically using JavaScript with the following code: <img id="drag0" src="http://localhost:34737/Images/MainSlider/A(1).jpg" class="col-4" draggable="true" ondragstart="drag(event)"> and I have a drag method setup ...

The function iframe.scrollTo() is not effective for scrolling through Excel or PowerPoint documents on an iPad

I am trying to create a custom scrolling feature for iframe content specifically for iPad. Currently, I have set up my iframe like this: <div id="scroller" style="height: 300px; width: 100%; overflow: auto;"> <iframe height="100%" id="iframe" ...

What could be causing this error to occur? I've already got node.js installed on my system

When I enter npm init in the Visual Studio Code - Insiders terminal, I get the following error message: npm init npm : The term 'npm' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the ...

Navigate to a new tab using this.router.navigate

Is there a way to redirect the user to a specific page with ${id} opening in a new tab, after clicking a button in an angular material dialog box? I want to leave the dialog box open while querying the new page. Currently, the redirect happens but not in a ...

What is the most effective method for defining 2 routes that point to the same component?

Although it may seem straightforward, I'm struggling to find the most efficient method for this particular scenario in Vue.js. I am using Vue Cli 3 and I need to have multiple routes leading to the same Home page within the application. The idea is ...

Tips for displaying a child React component for a specific duration

One of the React components I have is called PopUpBanner, which is utilized to display messages. For instance, in my login component, I employ it in this manner. If an error arises, the bannerMessage state is updated to showcase the message on the banner: ...