What is the best way to group similar values together in individual arrays in JavaScript?

I have a JavaScript function that I'm working on which takes an array as input and should return another array where similar elements are grouped together in sub-arrays. The initial array is passed in, and the output should be a new array.

For instance, if I call

groupfunction([1, 2, 4, 591, 392, 391, 2, 5, 10, 2, 1, 1, 1, 20, 20])
, it ideally should give me
[[1, 1, 1, 1], [2, 2, 2], 4, 5, 10, [20, 20], 391, 392, 591]
. However, the current output is
[[1, 1, 1, 1], 2, [4, 4, 4], [591, 591], 392, 391, 5, 10, 20]
for some reason. What can I do to properly group identical elements into separate sub-arrays within the main array?

I came across these helpful questions while trying to resolve my issue:

  • Create an array with same element repeated multiple times
  • Delete zero values from Array with JavaScript
  • How to create an array containing 1...N
const findnumberofinstances = (array, element) => { // This function finds how many times a specific element occurs in an array
    let numberoftimes = 0;
    const functionisequal = (input1) => {if(input1 === element) {return true}
    else {return false}};
    const indexofelement = array.findIndex(functionisequal);
    while(array.includes(element) === true) {
        array.find(functionisequal);
        numberoftimes += 1;
        array.splice(indexofelement, 1);
    }
    return numberoftimes;
}

const finduniquevalues = (arr) => { // This function reduces an array to only have unique values.
    const map = [];
    for (let value of arr) {
        if (map.indexOf(value) === -1) {
            map.push(value);
        }
    }
    return map;
};

const removeElementsWithValue = (array, val) => { // This function removes specific values from an array
    var i = array.length;
    while (i--) {
        if (array[i] === val) {
            array.splice(i, 1);
        }
    }
    return array;
}

const removezeroes = (array) => {return removeElementsWithValue(array, 0)} // This function removes zeroes from an array

const repeatelement = (elem, n) => { // This function repeats an element, effectively multiplying an array of one value [value] by n so that value occurs n times.
    var arr = [];

    for (var i = 0; i < n; i++) {
        arr = arr.concat(elem);
    };

    return arr;
};

const findnumberofeachelement = (array) => {let blank = []; // This function finds how many of each element is in an array.
    let arraycopy = array.concat([]);
    let sortedArray = array.slice().sort();
    let arraycopysorted = arraycopy.slice().sort();
    for(element of arraycopysorted){let num = findnumberofinstances(sortedArray, element);
        blank.push(num);
    }
    return removezeroes(blank);
}

const groupfunction = (array) => { // This function groups elements that are identical into sub-arrays only if there are more than one of the elements.
    let sum = [];
    let unique = finduniquevalues(array);
    let blank = [];
    let number = findnumberofeachelement(array);
    for(let i=0; i< unique.length; i++) {
        if(number[i] > 1) {
            sum = repeatelement(unique[i], number[i])
            blank.push(sum);
        }
        else {
            sum = unique[i]
            blank.push(sum)
        }

        sum = []
    }
    return blank
}

console.log(groupfunction([1, 2, 4, 591, 392, 391, 2, 5, 10, 2, 1, 1, 1, 20, 20])) // This should return [[1, 1, 1, 1], [2, 2, 2], 4, 5, 10, [20, 20], 391, 392, 591].

Answer №1

If you want to group your array based on each value using an object accumulator, you can utilize the array#reduce method.

const customGrouping = arr => Object.values(
    arr.reduce((result, value) => {
      result[value] = result[value] || [];
      result[value].push(value);
      return result;
    }, {}))
  .map(group => group.length === 1 ? group[0] : group);

console.log(customGrouping([1, 2, 4, 591, 392, 391, 2, 5, 10, 2, 1, 1, 1, 20, 20]));
.as-console-wrapper { max-height: 100% !important; top: 0; }

Answer №2

let numbers = [1,2,3,3,5,1, 10, 9, 10];

let updatedNumbers = numbers.reduce((resultArray,number ) => {
  const foundItem = resultArray.find(item =>  item === number); // find item in array;

  if (foundItem ){ // if we found item;
    const index = resultArray.indexOf(foundItem);
    resultArray.splice(index, 1, [foundItem, foundItem]) // convert item to array
  } else {

    let inserted = false; // we'll push item into array or subarray   
    resultArray.forEach(item => {
      if (item instanceof Array && item === number){
        item.push(number);  // append item to subarray
        inserted = true;
      }
    }) 
    if (!inserted) resultArray.push(number); // append as item;

  }
  return resultArray; 
}, [] /* initial array */) 


console.log(JSON.stringify(updatedNumbers))

Answer №3

Here is the solution I've come up with. It may not be straightforward, but it should provide the correct outcome.

function groupNumbers(array) {
    array.sort(function(a, b){return a - b})
    const map = new Map()
    const order = []
    array.forEach(e => {
        if (map.has(e)) {
            map.get(e).push(e)
        } else {
            map.set(e, [e])
            order.push(e)
        }
    })

    const finalResult = []

    order.forEach(e => {
        const group = map.get(e)
        if (group.length == 1) {
            finalResult.push(group[0])
        } else {
            finalResult.push(group)
        }
    })

    return finalResult
}

console.log(groupNumbers([1,2,4,591,392,391,2,5,10,2,1,1,1,20,20]))

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

Parsing error: Unforeseen token encountered. Consider adding a supplementary loader to manage the output of these loaders

Could someone please break down this syntax message?.length === 1 and show me how to convert it into standard JavaScript? https://i.stack.imgur.com/20Ui6.png I am encountering an error when trying to use a Vue.js component that I downloaded from another ...

What is the best way to graph a 2D array by converting it into two separate 1D arrays?

I need to split the Latitude and Depth data into two separate numpy arrays. [['Latitude' 'Depth'] ['28.00303425' '5067.9097'] ['28.00304059' '5068.656'] ... ['28.01996016' '5067 ...

Sluggish Performance of Material UI Table

Hey there! I've been working with Material-UI for a large data table, but I've noticed it's quite slow. Before reaching out on Github, I wanted to see if other users have any tips or workarounds to help improve performance. Here is the code ...

The mouse pointer position in THREE.js does not align with the arrow tip during events

I am currently grappling with figuring out how to accurately determine the position of click events on the screen while using THREE.js alongside an Orthographic camera. Unfortunately, the position that I have managed to calculate (similarly to what is des ...

Interactive elements embedded within an image - digital board game

I'm currently working on integrating a board game into React, and I am facing some difficulties in figuring out how to translate the board squares shown in the image into data. Is there a method through which I can assign unique IDs to each square di ...

Vue.js <v-data-table> - Automatic sorting/ custom sorting options

I am trying to arrange the numerical data in a Vue.js data-table in descending order right from the start. I want it to look like the screenshot provided below. Screenshot of My Desired Result The data that needs to be arranged in descending order is the ...

Understanding the concept of for loops in JavaScript and incorporating them in CSS styling

Hello there! I initially used this code to draw 12 lines, but now I am looking to incorporate a for loop and implement it in CSS. Can someone please guide me on how to proceed? <!DOCTYPE html> <html> <head> <style> #straigh ...

Tips for achieving a dimmed content effect on Semantic UI React within a NextJS project

I'm currently facing an issue with incorporating dimmed content into the Semantic UI React sidebar on Next.js... Here is the example of dimmed content on Semantic UI: https://i.sstatic.net/5dOGK.png This is the layout code I am using: import React, ...

Struggling to establish a default value for an AngularJS select dropdown

I'm diving into the world of AngularJS and facing a challenge with setting a default value on a select box. I've successfully listed objects in the select box and binding it to the model works seamlessly. However, as soon as I introduce a default ...

Tips for sending a string from the state of a React component to an external Python script

My journey into ReactJS and web development is just beginning. I am currently working on a web application where users can input mathematical expressions as strings. Upon submitting the input, I intend to process it using a Python script and display the o ...

Extract a value from a json document

Hey there! I'm looking to create an unwhitelist command. When a user is mentioned or their ID is provided, I want it to be removed from the JSON file without checking if the ID exists. Do you have any suggestions on how to accomplish this? Here is my ...

In the Opera browser, the closing script tags seem to mysteriously vanish

I recently built a website using bootstrap and implemented the JQuery load function to merge separate HTML files into one for better organization. The site is currently live on github pages. However, I've encountered an issue specifically with Opera ...

Strategies for Refreshing a Component After Modifying Data in the Store

Having trouble updating my table component when the data in my store changes. I have a simple table using v-for as shown below: <tr v-for="d in getDatas" v-bind:key="d.id"> and buttons to navigate between pages: <button class= ...

What is the method to retrieve data within a resolved Promise in JavaScript?

Currently, I am delving into the world of promises for the very first time. My goal is to retrieve data (in the form of an array) from two distinct endpoints. Consequently, I have drafted the following code. Upon inspecting my console, I notice that [Promi ...

JavaScript callbacks using customized parameters

I am currently grappling with the challenge of incorporating an asynchronous callback in node without prior knowledge of the potential arguments. To provide more clarity, let me outline the synchronous version of my objective. function isAuthorized(userI ...

Nested JSON array is being shown as [Object Object] within a TextField

I am facing an issue with mapping two sets of JSON data, which I will refer to as Set 1 and Set 2. In Set 1, the data (named sizingData) is being mapped to text fields using the following function: const fillTextField = () => { let result = []; ...

Is there a built-in way to update a Django template from the server side in response to an event?

As a novice Django developer, my task is to create an auction website. I need to enhance the template that displays item listings and bids, ensuring that the latest bids are updated in real-time without the need for users to refresh the page. While consid ...

Validation of textfields using React.js

Currently, I am working on implementing a validation feature in ReactJS. Specifically, I have a field named "name" and my requirement is that every time a name is entered, it must be equal to or greater than 2 characters. The validation works fine when t ...

What is the technique for wrapping a component with a rectangle box in ReactJs?

Do you like the design in this example image? I attempted to create a similar layout using Material UI Box, but unfortunately, it only displays the text without rendering the box itself. Take a look at the code I used: import * as React from 'react& ...

Creating a new instance in C# by combining a struct, an enum, and

Recently, I came up with an idea to create a struct which I named Example. Here is the structure: [System.Serializable] public struct Example { public enum Categories {example, test} [SerializeField] private Categories lineCategory ; public ...