Reordering items within an array of objects using JavaScript

I am working with an array of objects that needs to be sorted by category, and I also need to find the total number of items in each category. In the example provided below, all categories with "toys" should be grouped together for easier counting, like in this case where there are 2 items in the "toys" category.

[
 { "category": "toys", "name": "cycle", "itemID": 1594, "price": 1594},
 { "category": "furniture", "name": "chair", "itemID": 15954, "price": 1594},},
 { "category": "furniture", "name": "table", "itemID": 15344, "price": 1594},},
 { "category": "books", "name": "twoLittle", "itemID": 153594, "price": 1594},},
 { "category": "electronic", "name": "Tape", "itemID": 134594, "price": 1594},},
 { "category": "books", "name": "oneLittle", "itemID": 1594436, "price": 1594},},
 { "category": "electronic", "name": "TV", "itemID": 159446, "price": 1594},
 { "category": "toys", "name": "car", "itemID": 1534694, "price": 1594},
]

Would appreciate any guidance on how to approach this issue.

Thanks a lot for your help.

Answer №1

To implement a custom sorting method, you can utilize the localeCompare function. Additionally, you can employ the array#reduce method to determine the count of each unique category.

const data = [{ "category": "toys", "name": "cycle", "itemID": 1594},{ "category": "furniture", "name": "chair", "itemID": 15954},{ "category": "furniture", "name": "table", "itemID": 15344},{ "category": "books", "name": "twoLittle", "itemID": 153594},{ "category": "electronic", "name": "Tape", "itemID": 134594},{ "category": "books", "name": "oneLittle", "itemID": 1594436},{ "category": "electronic", "name": "TV", "itemID": 159446},{ "category": "toys", "name": "car", "itemID": 1534694}];

data.sort((a,b) => a.category.localeCompare(b.category));
console.log(data);

var distinctCount = data.reduce((r,{category}) => {
  r[category] = (r[category] || 0) + 1;
  return r;
},{})

console.log(distinctCount);
.as-console-wrapper { max-height: 100% !important; top: 0; }

For ES5 Syntax:

var data = [{ "category": "toys", "name": "cycle", "itemID": 1594 }, { "category": "furniture", "name": "chair", "itemID": 15954 }, { "category": "furniture", "name": "table", "itemID": 15344 }, { "category": "books", "name": "twoLittle", "itemID": 153594 }, { "category": "electronic", "name": "Tape", "itemID": 134594 }, { "category": "books", "name": "oneLittle", "itemID": 1594436 }, { "category": "electronic", "name": "TV", "itemID": 159446 }, { "category": "toys", "name": "car", "itemID": 1534694 }];

data.sort(function (a, b) {
  return a.category.localeCompare(b.category);
});
console.log(data);

var distinctCount = data.reduce(function (r, obj) {
  var category = obj.category;
  r[category] = (r[category] || 0) + 1;
  return r;
}, {});

console.log(distinctCount);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Answer №2

It appears that your goal is to create an object with the category as the key:

const categorizedItems = items.reduce((acc, item) => {
    if (!acc[item.category]) {
        acc[item.category] = [];
    }
    acc[item.category].push(item);
    return acc;
}, {});

You can now access the toys category and its length like this:

   const numberOfToys = categorizedItems.toys.length; //2

If you wish to loop through the toys:

categorizedItems.toys.forEach(toy => {
    console.log(toy.name);
});

This way, you achieve automatic sorting (items are grouped by category), and it's easy to find out how many items are in each category (simply check the .length property).

const items = [
 { "category": "toys", "name": "cycle", "itemID": 1594},
 { "category": "furniture", "name": "chair", "itemID": 15954},
 { "category": "furniture", "name": "table", "itemID": 15344},
 { "category": "books", "name": "twoLittle", "itemID": 153594},
 { "category": "electronic", "name": "Tape", "itemID": 134594},
 { "category": "books", "name": "oneLittle", "itemID": 1594436},
 { "category": "electronic", "name": "TV", "itemID": 159446},
 { "category": "toys", "name": "car", "itemID": 1534694}
]

const categorizedItems = items.reduce((acc, item) => {
    if (!acc[item.category]) {
        acc[item.category] = [];
    }
    acc[item.category].push(item);
    return acc;
}, {});

console.log(categorizedItems, categorizedItems.toys.length);

Answer №3

Here is a simple and concise one-liner code snippet for you to use:


data = [
     { "category": "toys", "name": "cycle", "itemID": 1594},
     { "category": "furniture", "name": "chair", "itemID": 15954},
     { "category": "furniture", "name": "table", "itemID": 15344},
     { "category": "books", "name": "twoLittle", "itemID": 153594},
     { "category": "electronic", "name": "Tape", "itemID": 134594},
     { "category": "books", "name": "oneLittle", "itemID": 1594436},
     { "category": "electronic", "name": "TV", "itemID": 159446},
     { "category": "toys", "name": "car", "itemID": 1534694}
]

data.sort(function(a, b) {
    return (a.category)<(b.category);
});

count = function (ary, classifier) {
    classifier = classifier || String;
    return ary.reduce(function (counter, item) {
        var p = classifier(item);
        counter[p] = counter.hasOwnProperty(p) ? counter[p] + 1 : 1;
        return counter;
    }, {})
};
countByCategory = count(data, function (item) {
    return item.category
});

Answer №4

I've simplified the process into easy steps.

  1. Calculate the totals to enable further analysis like averages later on
  2. Add the objects into an array (one for each category)
  3. Arrange the array based on a chosen property (such as count, name, or category)

The outcome will be an array of objects with a count property, which could be useful for rendering or templating purposes.

Check out this JSFiddle link for reference!

var data = [
     { "category": "toys", "name": "cycle", "itemID": 1594},
     { "category": "furniture", "name": "chair", "itemID": 15954},
     { "category": "furniture", "name": "table", "itemID": 15344},
     { "category": "books", "name": "twoLittle", "itemID": 153594},
     { "category": "electronic", "name": "Tape", "itemID": 134594},
     { "category": "books", "name": "oneLittle", "itemID": 1594436},
     { "category": "electronic", "name": "TV", "itemID": 159446},
     { "category": "toys", "name": "car", "itemID": 1534694}
    ];
    var result={},arr=[], sorted;
    
    // Calculate the totals and preserve original data
    for (var i = data.length - 1; i >= 0; i--) {
        var item = data[i],
              cat = item.category;
         result[cat] = result[cat] || {name:item.name, category: cat, count:0};
         result[cat].count ++; 

    }
    
    // Place the results into an array for sorting
    for (var o in result){arr.push(result[o])};
    
    // Sort based on desired property - in this case, count
    sorted =  arr.sort(function(a,b) {return (a.count > b.count) ? 1 : ((b.count > a.count) ? -1 : 0);} ); 
    console.log(sorted)

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

Leveraging the source of an image from asset variables

Lately, I've been experiencing issues with displaying images on my page, specifically when trying to show a list of images. The problem arises when attempting to store the image URL in a variable or object instead of hardcoding it directly into the s ...

Can you explain the distinction between using this.function and making a function call in React?

I'm new to React and recently came across some code in a project that confused me. Could someone please clarify the distinction between this.function and the following function call used in a React event handling prop? <button onClick={this.clickH ...

A guide on incorporating multiple nested loops within a single table using Vue.js

Is it possible to loop through a multi-nested object collection while still displaying it in the same table? <table v-for="d in transaction.documents"> <tbody> <tr> <th>Document ID:</th> &l ...

Rendering Error - Animating text using React and Material-UI

Looking for a way to create a scrolling effect line by line? I have a component with name, pronouns, and some humble sub-text that should scroll one item at a time. To handle the scrolling feature, I've set up a separate component called TitleScroll. ...

Retrieve records with at least one connection, but display all of them

After creating this entry, it now consists of 2 tags - tag1 and tag2. { "id": "d87de1d9-b048-4867-92fb-a84dca59c87e", "name": "Test Name", "tags": [ { "id": "fa0ca8fd-eff4-4e58-8bb0-a1ef726f01d4", "name": "tag1", "organizationI ...

The dropdown items in the Tailwind menu fail to pop out from the React Next.js card component

My dropdown menu component, called DropdownWithSearch, is encountering an issue where it opens inside the card component (UserAssignForm) instead of popping out as expected. You can view the problem here. The DropdownWithSearch component import { Menu, Tr ...

Pricing determined by location on a website created with HTML

We are looking to customize our HTML5/CSS3 website by displaying different pricing tables based on the location of each visitor. Our goal is to have a fixed price for users from Singapore while showing a different price for visitors from other parts of th ...

Obtain information from a website, then initiate a lambda function to send an email and store the data in

As a beginner, I came across two different sets of instructions online. The first one was about using AWS Lambda to send data (Contact us - Email, Phone, etc) to my email via Amazon API Gateway and Amazon SES: https://aws.amazon.com/blogs/architecture/cre ...

Trouble retrieving desired data from an array of objects in React Native

I'm having trouble retrieving values from an array of objects in my state. When I try to access the values, it only prints out "[Object Object]". However, when I stored the values in a separate array and used console.log, I was able to see them. Here ...

Struggling to employ JavaScript events when submitting a form to verify the fields

My goal is to create a form with fields that have real-time validation using JavaScript. I have achieved this by utilizing Java events in the following way: Text field onkeyup: This event sends a request to check for errors in the field every time a key ...

Invoke a function from a page that has been reloaded using Ajax

After making an Ajax request to reload a page, I need to trigger a JavaScript function on the main page based on certain database conditions. This is necessary because I require some variables from the main page for the function. PHP code: if($reset_regi ...

Simply click on a single checkbox in ReactJS

Is there a way to implement a method in which clicking on one checkbox will automatically deselect the other checkboxes, allowing only one selection at a time? import React, { Component } from 'react'; export default class Tablerow extends Comp ...

Show the name of the channel on the FeatherJS chat application

I've been using this repository as a guide to develop a chat application. Currently, I'm working on displaying the channel name (the default room where users are logged in) in the chat client. Is there a way to retrieve channel information from ...

Tips for creating brief animations

I am currently working with a moving div in JavaScript that continues to move for a period of time after the key is released. I am looking for a way to immediately stop the animation upon releasing the key. The animation is controlled by a switch statemen ...

Do arrays vary in size based on covariance?

Can the new type std::array be used polymorphically in terms of array size? For example, if there is a function defined as: void DoSomething(std::array<int, 5>& myArray) { /* ... */ } Then is it feasible to perform the following (even if it ...

Creating a tool that produces numerous dynamic identifiers following a specific format

I am working on a function to create multiple dynamic IDs with a specific pattern. How can I achieve this? followup: Vue.js: How to generate multiple dynamic IDs with a defined pattern Details: I am developing an interactive school test application. Whe ...

Unveiling the Evasive Final Element in a JavaScript Array

Having a Javascript array named full_range: const range1 = _.range(1, 10, 0.5); const range2 = _.range(10, 100, 5); const range3 = _.range(100, 1000, 50); const range4 = _.range(1000, 10000, 500); const range5 = _.range(10000, 105000, 5000); const full_ran ...

Guide to retrieving all selected options from a multi-select box using jQuery

I have a lengthy form that is constantly changing and includes multiple Select Options such as <select class="common_dt_select" id="select_15" data-col-index="15"> <option value="">All CC Status</option> <option value="0">De ...

Utilizing separate JavaScript files in Bootstrap 5: A guide to implementation

I am currently using Bootstrap, but I am looking to decrease the size of the Javascript files being used. My main requirements are dropdown/collapse and occasionally carousel functionalities, so I only want to include those specific scripts. Within the "d ...

utilize angular4 to dynamically link images from twitter based on certain conditions

Currently, I am attempting to retrieve the URL of images from tweets only if the tweet contains an image. I have been successful in fetching tweets and some images, but the issue arises when a tweet does not have an image, causing it to break and stop disp ...