Developed technique for grouping arrays in JavaScript based on frequency of occurrence

I have a collection of arrays in javascript and I need to perform some calculations.

Here is how my array looks:

https://i.sstatic.net/m0tSw.png

In each array: - The first value represents a code. - The second value indicates the size. - And the third value denotes the count.

My objective is to identify all groups where the counts are all 0.

For instance:

  • If "NVY" "S" has a count of 0 (not 28), then I want to retrieve ["sjm-NVY"];

Here's what I've attempted so far:

var a    = [];
$.each(arr[21].splits, function(idx, val) {
    console.log(val);   
    var current_code = arr[21].splits[idx][0];

    a[current_code] = [];
    a[current_code].push(arr[21].splits[idx]);
});  

However, I haven't been able to find the correct solution. Thank you for any help!

The dataset:

{"code":"sjm","splits":[["FOG","L","0"],["FOG","XL","-1"],["FOG","XXXL","2"],["FOG","S","7"],["FOG","M","0"],["FOG","XXL","6"],["BLK","LT","30"],["BLK","XLT","23"],["BLK","XXXLT","0"],["BLK","L","102"],["BLK","XL","302"],["BLK","XXXL","64"],["BLK","S","25"],["BLK","XXLT","0"],["BLK","M","485"],["BLK","XXL","159"],["BGE","L","106"],["BGE","XL","41"],["BGE","XXXL","15"],["BGE","S","4"],["BGE","M","39"],["BGE","XXL","0"],["RED","L","36"],["RED","XL","41"],["RED","XXXL","8"],["RED","S","5"],["RED","M","19"],["RED","XXL","2"],["NVY","L","0"],["NVY","XL","0"],["NVY","XXXL","0"],["NVY","S","28"],["NVY","M","0"],["NVY","XXL","0"]]}

P.S There are no color codes on the screen above where all values in the group are 0, hence nothing to display.

Answer №1

My assumption, based on your discussion about grouping, is that you would start by using the reduce function followed by the filter method

To group your arrays by the first index, you can implement it like this:

function groupBy( arr, t ) {
  return arr.reduce( (agg, c) => {
    const key = t(c);
    if (!agg[key]) {
      agg[key] = [];
    }
    agg[key].push( c );
    return agg;
  }, {} );
}

You can then utilize the above function as follows:

const result = groupBy( arr[21], item => item[0] );

This will give you an object structure similar to:

{ "NVY": [["NVY", "S", "28"], ...] }

Next, you can identify those items with a total count of 0:

function find( obj, predicate ) {
  return Object.keys( obj ).filter( key => predicate( obj[key] ) );
}

Usage example for the above function:

const groups = find( result, items => !items.some( i => i[2] !== "0" ) );

The output, in case NVY only contains items with a count of "0", would be:

["NVY", "..."]

You can further combine this information with your code property

In summary, combining all these steps will result in something like:

 // Code snippet provided here

Answer №2

Answer:

If you want to manipulate your data in various ways, you can create an Inventory Constructor that allows flexible parsing options.

code:

function Inventory( from ) {
    return {
        data: from,
        getBy: function( type ) {
            if ( ![ "code", "size", "quantity" ].includes( type.toLowerCase() ) ) throw new Error( "Incorrect Inventory::getBy Type" );
            return function( value ) {
                return Inventory( 
                    from.filter( ( [ code, size, quantity ] ) => 
                        new Function( "code, size, quantity", `return ${type} === '${value.toUpperCase()}'` )( code, size, quantity ) 
                    ) 
                );
            }
        }
    }
}

Example:

let data={splits:[["FOG","L","0"],["FOG","M","0"],["FOG","XL","-1"],["FOG","XXXL","2"],["NVY","M","0"],["NVY","L","0"],["NVY","S","0"]]};


function Inventory(from) {
return {
data: from,
getBy: function(type) {
if (!["code", "size", "quantity"].includes(type.toLowerCase())) throw new Error("Incorrect Inventory::getBy Type");
return function(value) {
return Inventory(from.filter(([code, size, quantity]) => new Function("code, size, quantity", `return ${type} === '${value.toUpperCase()}'`)(code, size, quantity)));
}
}
}
}

let Inv = Inventory(data.splits),
noQuantity = Inv.getBy("quantity")("0").data;

console.log("Items with 0 Quantity: ");
console.log(noQuantity);

Why so detailed?

At first glance, this solution may seem elaborate. But it offers versatility and adaptability, unlike other answers. It enables nested searches and ensures maintainability and reusability of code.

Why choose this approach?

  • Nested searches are possible
  • Enhanced maintainability and reusability

This solution addresses evolving needs and edge cases efficiently with minimal code. The explanation below delves deeper into how it functions.


Explanation: How it works

We start by creating a simple Inventory Constructor to store and manipulate the data provided.

For example:

function Inventory(from) {
   return { 
      data: from
  }
}

The constructor stores the inventory data within its property. You can access this data for further manipulation.

Example:

let data={splits:[["FOG","L","0"],["FOG","M","0"],["FOG","XL","-1"],["FOG","XXXL","2"],["NVY","M","0"],["NVY","L","0"],["NVY","S","0"]]};

function Inventory(from) {
     return {
        data: from
      }
    }

let Inv = Inventory(data.splits);
console.log(Inv);


To enable searching through the data based on specific criteria like quantity or size, we implemented a filtering method called getBy.

For instance:

function Inventory(from) {
    return {
        data: from,
        getByQuantity: function(quantity) {
            return from.filter(([, , q]) => quantity === q);
        }
    }
}

Example:

let data={splits:[["FOG","L","0"],["FOG","M","0"],["FOG","XL","-1"],["FOG","XXXL","2"],["NVY","M","0"],["NVY","L","0"],["NVY","S","0"]}];

function Inventory(from) {
  return {
    data: from,
    getByQuantity: function(quantity) {
      return from.filter(([, , q]) => quantity === q);
    }
  }
}

let Inv = Inventory(data.splits),
noQty = Inv.getByQuantity("0");

console.log( noQty );


However, when multiple filters are required, the implementation might become cumbersome. To address this issue, we introduced the Templating Pattern along with recursion in our Inventory Constructor.

With this enhancement, you can perform successive searches on the data until you obtain the desired result effortlessly.

Here's a brief overview of the steps involved:

  • Flexible search capability with getBy method
  • Comparison operations using the filterBy method

Through iterative searches, you can navigate through the inventory data, reducing complexity while ensuring precise results.

Final Solution:

function Inventory(from) {
    return {
        data: from,
        getBy: function(type) {
            if (!["code", "size", "quantity"].includes(type.toLowerCase())) throw new Error("Incorrect Inventory::getBy Type");
            return function(value) {
                return Inventory(from.filter(([code, size, quantity]) => new Function("code, size, quantity", `return ${type} === '${value.toUpperCase()}'`)(code, size, quantity)));
            }
        },
        filterBy: function(comparison) {
            return Inventory(from.filter(([code, size, quantity]) => new Function("code, size, quantity", `return ${comparison};`)(code, size, quantity)));
        }
    }
}

let noQty = Inventory(data.splits).getBy("quantity")("0");

Final Example:

let data={splits:[["FOG","L","0"],["FOG","M","0"],["FOG","XL","-1"],["FOG","XXXL","2"],["NVY","M","0"],["NVY","L","0"],["NVY","S","0"]}};

function Inventory(from) {
return {
data: from,
getBy: function(type) {
if (!["code", "size", "quantity"].includes(type.toLowerCase())) throw new Error("Incorrect Inventory::getBy Type");
return function(value) {
return Inventory(from.filter(([code, size, quantity]) => new Function("code, size, quantity", `return ${type} === '${value.toUpperCase()}'`)(code, size, quantity)));
}
},
filterBy: function(comparison) {
return Inventory(from.filter(([code, size, quantity]) => new Function("code, size, quantity", `return ${comparison};`)(code, size, quantity)));
}
}
}

let Inv = Inventory(data.splits),
allNvyNoQuantity = Inv.getBy("code")("NVY").getBy("quantity")("0").data;

console.log("All NVY items with 0 Quantity: ");
console.log(allNvyNoQuantity);


Conclusion:

In conclusion, the enhanced Inventory Constructor provides a versatile and efficient way to manage and analyze inventory data. Its flexibility in search criteria and comparison operations make it a powerful tool for data manipulation.

Happy coding!

Answer №3

Below is a handy function that can be used to search for specific counts within an array based on the provided structure:

function findCountInArray(arr, code, count) {
    var results = [];

    $.each(arr, function (index, subArr) {
        var currentCount = subArr[2];
        var groupCode = code + "-" + subArr[0];
        
        if (currentCount == count && results.indexOf(groupCode) === -1) {
            results.push(groupCode);
        }
    });

    return results;
}

console.log(findCountInArray(data.splits, data.code, 0));

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

I have noticed that there are 3 images following the same logical sequence, however only the first 2 images seem to be functioning correctly. Can you help

Update: I have found a solution that works. You can check it out here: https://codepen.io/kristianBan/pen/RwNdRMO I have a scenario with 3 images where clicking on one should give it a red outline while removing any outline from the other two. The first t ...

The click event is activated following the :active selector being triggered

My Angular application features a button with a slight animation - it moves down by a few pixels when clicked on: &:active { margin: 15px 0 0 0; } The button also has a (click)="myFunction()" event listener attached to it. A common issue arises w ...

Adjust the contents of an HTTP POST request body (post parameter) upon activation of the specified POST request

Is there a way to intercept and modify an HTTP Post Request using jQuery or JavaScript before sending it? If so, how can this be achieved? Thank you. ...

How to properly remove a 2D array?

I found an interesting discussion in this answer that sparked my curiosity. In the comments, it was suggested to delete the dynamically allocated 2D array in reverse order. I'm not entirely clear on the reasoning behind this. Here is the code snippet ...

Fetching data in a post request seems to be causing an issue with FormData image being

I've implemented a profile picture file upload system with the following HTML: <form enctype="multipart/form-data" id="imageUpload" > <img id="profileImage" src="./images/avatar.png& ...

Adding a stylesheet dynamically in Angular 2: A step-by-step guide

Is there a method to dynamically add a stylesheet URL or <style></style> in Angular2? For instance, if the variable isModalOpened is set to true, I want to apply certain CSS styles to elements outside of my root component, such as the body or ...

Enable the ability to scroll and click to navigate an overlapping Div element

A customer has a website with a dark teal design and is not pleased with the appearance of the scroll bar, as it disrupts the overall style. The client requested that I find a solution without using third-party libraries, and one that they can easily under ...

Tips for incorporating a favicon in a React application

Having trouble adding a favicon to my React application. I followed the instructions in this post, but it's not working for me. I placed the favicon.ico file inside the public folder where index.html resides. This is how my directory structure looks ...

What is the best way to showcase a local image in the console using nwjs?

I am currently developing a desktop application using NW.js (node-webkit). In relation to this topic google chrome console, print image, I am attempting to display an image in the console. Following the suggestion from the aforementioned topic, the follo ...

Trouble with Mocha async hooks execution?

I keep encountering the issue of receiving 'undefined' for the page in this setup. It appears that none of Mocha's hooks are being executed. I've attempted adding async to the describe at the top level, used done statements, and even tr ...

Presenting JSON data in a table format on-the-fly even without prior knowledge of the data's structure or field names

When working with my application, I will be receiving data in JSON format and I am looking to showcase this data in a tabular form within a web browser. It's important to mention that I won't know beforehand the structure or field names of the re ...

What is more effective: utilizing document fragments or string concatenation for adding HTML to the DOM?

My task involves adding a collection of cards to the DOM. html <div class="card"> <div class="card-title">Card 1</div> <div class="card-subtext">This is card 1</div> </div> js let ...

Arrange the elements of the array in alphabetical order and categorize them based on their initial letter

Is there a way to organize an array alphabetically and categorize it by the first letter in PHP? I am curious about how to achieve this using PHP. I have a list of names that I retrieve from the database. Specifically, I am interested in: https://i.sta ...

The getElementBy method is failing to pass the value in the document

Here is the javascript code snippet I am using: document.getElementById('district').value = dist.long_name "this line is passing the value" document.getElementById('city').value = route.long_name "this doesn&apos ...

The nodemailer module in Node.js encountered an issue while trying to send an email, resulting

Looking to confirm registration, I want to send an email from my server (kimsufi). To accomplish this, I am utilizing nodemailer which can be found at https://github.com/andris9/Nodemailer Encountering the following error: Error occurred Sendmail exited ...

What is the best method for gathering information from multiple input fields?

I'm currently working on developing a Polymer application that includes a search button with multiple input boxes. I want the search operation to consider all the inputs from these boxes when performing a search. Here is an image depicting the scenar ...

Tips for Utilizing jQuery each Loop

I am attempting to create a foreach loop that will iterate through hidden values on the page, compare them with an external API using Ajax, and display the API results in a < ul > for example. Sample model ITEM1 metavalue (which needs to be che ...

How can I extract the page's output using JQuery?

Being a rookie in this area, I am eager to learn how to extract specific content from a page using AJAX in JQuery. Currently, I have been able to fetch the data of a page and display it as text: $.ajax({ type: "POST", url: "myfile.html", su ...

Having trouble setting up Strongloop for Loopback v.3 on macOS Catalina?

I'm currently in the process of understanding Loopback v3 (which is being utilized on a project site where I'm actively involved), and I'm attempting to follow the tutorials provided. One of the crucial steps involves installing Strongloop ...

Converting dates in Javascript

I have retrieved a date/time value of "20131218" from an API response. My goal is to transform this date into the format "2013-12-18". In PHP, this can be easily achieved with the following code: echo date("Y-m-d", strtotime('20131218')); The ...