JavaScript: Condense array by only keeping unique values and their respective counts

I've taken on a challenging puzzle to solve. I have a multi-dimensional array in my Javascript code that is structured like this; Each feature is defined by an ID, a date (in string format), and a state.

Here's an example:

Features = [
    [1, "20200503", "Active"],
    [2, "20200503", "Closed"],
    [2, "20200503", "Closed"],
    [2, "20200502", "Closed"],
    [2, "20200501", "Active"],
    [2, "20200430", "Active"],
    [2, "20200430", "Active"],
    [3, "20200503", "New"],
    [3, "20200502", "New"],
];

My goal is to condense this array into a new one with the following result;

Features = [
    [1, 1, "Active"],
    [2, 3, "Closed"],
    [2, 3, "Active"],
    [3, 2, "New"],
];

I'm looking to perform a distinct operation based on the ID and state while counting the occurrences of each date.

Is it feasible to achieve this using Javascript?

Answer №1

To achieve the desired outcome, you should utilize the reduce method to condense the array. Thankfully, there exists a handy function for this exact purpose! By providing an empty array as the second argument of the reduce function, you can use it as an accumulator and compare the current element with the previous one to determine the necessary actions.

data = data.reduce((accumulator, current, index, array) => {
  let previous = array[index - 1];

  if (index === 0 || current[0] !== previous[0] || current[2] !== previous[2]) accumulator.push([current[0], 1, current[2]]);
  else accumulator[accumulator.length - 1][1]++;

  return accumulator;
}, []);

Answer №2

function condenseAttrs(attributes) {
    // Retrieve unique identifiers and states
    var ids = new Set(attributes.map(attr => attr[0]);
    var states = new Set(attributes.map(attr => attr[2]);

    // Initialize array to store the condensed result
    const condensedResult = [];

    // Iterate through all permutations of IDs and States
    for (const id of ids) {
        for (const state of states) {
            // Count number of attributes with matching id and state
            let attrCount = attributes.filter(attr => attr[0] === id && attr[2] === state).length;
            
            // Check if there are any attributes with ID "id" and State "state"
            if (attrCount > 0)
                condensedResult.push([id, attrCount, state]);
        }
    }
    
    return condensedResult;
}

Invoke the function like this

var compressedAttributes = condenseAttrs(Attributes);

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

Executing an http.get request in Angular2 without using RxJS

Is there a method to retrieve data in Angular 2 without using Observable and Response dependencies within the service? I believe it's unnecessary for just one straightforward request. ...

What steps can be taken to gain entry to a directory and its nested subdirectories?

I have a function that can monitor files in directories and subdirectories, but it is unable to access files three levels deep within the subdirectories. I simply need to track any changes made to specific files and make modifications as needed, which req ...

What are some other options for pushing out data instead of using window.onbeforeunload?

I have an AJAX function that interacts with my PHP script. The purpose was to delete empty MySQL entries when the user closes the page. Initially, I thought window.onbeforeunload would be ideal for this task, but it seems in the latest version of Chrome i ...

Ways to transfer information between controllers in my situation

I am attempting to send data to my controller using the State Provider. This is an example of what I have: app.js $stateProvider .state('test', { url: '/te', views: { '&ap ...

Troubleshoot Nested Array URL Parameter Problems in Node.js

I am encountering an issue with extracting data from an array that I am sending to my API through an AXIOS call to Express. The call is sent successfully, but the issue arises when trying to access the data in the property_features parameter. Even though m ...

Why is the background object still showing in HTML after implementing z-index?

I'm currently working on a popup to display some preload content, but unfortunately it's not functioning properly. Instead of showing the preload content, it's displaying another element. <html> <script src="http://www.flygoldf ...

d3.json is unable to parse a value of 'Infinity

My goal is to retrieve data from an SQLite database and convert it into JSON format for use with d3.js in order to create a graph. I have successfully obtained this data in JSON format using the following URL: http://localhost:8085/SQLQuery/?date1=2019-03 ...

Issue with AngularJS: UI Router failing to show the template

I have set up the ui.router with xhtml templates. However, the template that I configured is not showing up. app.js ClaimsDB.config(function($stateProvider, $urlRouterProvider){ $urlRouterProvider.otherwise("/main"); $stateProvider .state('main& ...

Tips for creating visually appealing tables in ReactJS

For my school project, I need to create a table using ReactJs. I have already created the table but it needs improvement in terms of design. However, I am unsure how to modify my code to achieve the desired look. I tried looking on YouTube for tutorials, b ...

Use Javascript to dynamically load a PHP file with the include function

I've been searching for a solution to this issue with no luck so far. Spending hours trying to figure it out. On my PHP page, I'm making an SQL call and dynamically building the content. There's a list of items with onClick JavaScript funct ...

Filtering a deeply nested object based on an array of keys in JavaScript

I have received an object and an array. My task is to filter the object so that it only contains nodes where either the key or the value matches with the keys provided in the array. For example: Array containing keys - ['student1', 'STU&apo ...

Loading Vue bootstrap b-form-select initially triggers Vuelidate's $anyDirty to become true

My current issue arises from the input event triggering when I initially assign a value to the v-model. This data is fetched via an API, causing the form to be marked as dirty due to the change. However, this poses a problem in another component where the ...

Struggling with implementing checkboxes within an HTML div using JavaScript

Being a newcomer to programming, I am facing some challenges with HTML/JS. My goal is to create a dynamic checkbox list for adding tasks to complete. Despite researching on at least 10 websites, I haven't been able to make it work. I have thoroughly c ...

Activate the prompt for saving a static file on Flash

Is there a way to prompt a save dialog for a static file in Flash? The file could be local or remote. Specifically, I am looking to do this with a static image. Being new to AS and SO, it's surprising to see the range of complex solutions for what se ...

Creating a project that utilizes Bing Translate and the Node.js programming language

As I work on developing a web application that enables users to translate text using the Bing translator API, I am facing an issue. I attempted to execute a translator.js file via a script tag, but encountered a roadblock since Node.js code cannot be run t ...

What is the best way to activate an onchange function when using a <select> element?

Is there a way to automatically trigger a JavaScript function without the need for user input, while still having a default option selected? <select class="custom-select" name="" id="timer1numbers" onchange="getSelecte ...

Encountered an error: Unable to access property 'tween' of an undefined variable in the Masterslider.js script

My webpage features three sliders using Master Slider alongside Fullpage.js. var slider = new MasterSlider(); slider.setup('masterslider', { width: 300, height: 300, });   slider.control('lightbox'); slider.control('slidei ...

ng-select will solely output the term 'collection'

i am having an issue with a ng-select in my contact form. everything is being received correctly except for the value of the ng-select. Instead of getting the selected option from the ng-select, the system just returns the word "array". Below is the port ...

Tips for shrinking a sticky header when scrolling using Angular and JavaScript

Looking for a way to modify the header component in an Angular application so that it shrinks as the user scrolls down while maintaining its sticky functionality. How can I adjust the display of the lower half of the header to show no text when the user s ...

ng-repeat to prevent duplicate items from displaying

I intentionally have duplicates in my array of items and I am looking for a way to hide just one of them when clicked within my ng-repeat. Is there a way to hide only one of the duplicated items on click? I feel like I might be overlooking something, as ...