Can the characteristics of a group of objects be combined and sorted based on a different attribute?

Feeling a bit puzzled by my title,

Here's the issue at hand - I aim to destructure an array of objects to utilize its properties in a chartJS Line Graph.

Take a look at the replicated array below:

[{
    "page": "Page 1",
    "date": "2021-10-05",
    "visitors": 10
}, {
    "page": "Page 2",
   "date": "2021-10-05",
    "visitors": 20
}, {
    "page": "Page 3",
    "date": "2021-10-05",
    "visitors": 30
},{
    "page": "Page 1",
    "date": "2021-10-04",
    "visitors": 40
}, {
    "page": "Page 2",
    "date": "2021-10-04",
    "visitors": 50
}, {
    "page": "Page 3",
    "date": "2021-10-04",
    "visitors": 60
}]

Each entry consists of a date (date), number of visitors (visitors), and a page name (page)

For instance, if there are 2 dates and 3 pages, seeking to retrieve the visitor numbers per date per page will result in 6 entries (3 pages for each date) as shown in the example above.

How can I gather the visits for each page and create an array that contains unique page names & dates just once along with the corresponding visit numbers like:

[   {
        page: pageName,
        dates: [],
        numberOfVisits: [],
    },
    {
        page: pageName,
        dates: [],
        numberOfVisits: [],
    },
    {
        page: pageName,
        dates: [],
        numberOfVisits: []
    },
]

I attempted to streamline the array and filter it based on either dates or page names like so:

myArray.reduce((a, c) => {
    /* Filtering by date - only one page name is returned */
    let filtered = a.filter(el => (el.date === c.date));

    /* Alternatively, filtering by page name - results in only one date for each */
    /* let filtered = a.filter(el => (el.page === c.page)); */

    if (filtered.length > 0) {
        /* Summing up the number of visits - this method works in both scenarios */
        a[a.indexOf(filtered[0])].m_unique_visitors += +c.m_unique_visitors;

    } else {
        a.push(c);
    }
})
return a;

Answer №1

If you're looking to organize dates and visitors by page, I recommend utilizing the Array.reduce() method.

To maintain sorted output by date, it's essential to sort the input array beforehand.

The accumulator (acc) will store properties for each page, including a page name, a list of dates, and the number of visits array.

Utilize Object.values() at the end to obtain the required final array.

const data = [{ "page": "Page 1", "date": "2021-10-05", "visitors": 10 }, { "page": "Page 2", "date": "2021-10-05", "visitors": 20 }, { "page": "Page 3", "date": "2021-10-05", "visitors": 30 },{ "page": "Page 1", "date": "2021-10-04", "visitors": 40 }, { "page": "Page 2", "date": "2021-10-04", "visitors": 50 }, { "page": "Page 3", "date": "2021-10-04", "visitors": 60 }]

const sortByDate = ({ date: a}, { date:b }) => Date.parse(a) - Date.parse(b);

const result = Object.values(data.sort(sortByDate).reduce((acc, { page, date, visitors}) => { 
    acc[page] = acc[page] || { page, dates: [], numberOfVisits: []};
    acc[page].dates.push(date);
    acc[page].numberOfVisits.push(visitors);
    return acc;
}, {}))

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

An alternative output structure could include a visits array, where each element contains a date and visitors value.

const data = [{ "page": "Page 1", "date": "2021-10-05", "visitors": 10 }, { "page": "Page 2", "date": "2021-10-05", "visitors": 20 }, { "page": "Page 3", "date": "2021-10-05", "visitors": 30 },{ "page": "Page 1", "date": "2021-10-04", "visitors": 40 }, { "page": "Page 2", "date": "2021-10-04", "visitors": 50 }, { "page": "Page 3", "date": "2021-10-04", "visitors": 60 }]
   
const sortByDate = ({ date: a}, { date:b }) => Date.parse(a) - Date.parse(b);

const result = Object.values(data.sort(sortByDate).reduce((acc, { page, date, visitors}) => { 
    acc[page] = acc[page] || { page, visits: [] };
    acc[page].visits.push( { date, visitors});
    return acc;
}, {}));

console.log('Result:', result);
.as-console-wrapper { max-height: 100% !important; top: 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

Link the global to the Vue component

Is there a way to connect global filters, mixins, and additional features to a specific Vue Instance rather than the Vue object directly? For instance import Vue from 'vue.js' import App from './app' import demo from './mixins/dem ...

Choose to conceal beneath the table within Bootstrap 4

As a budding web developer, I am currently using Bootstrap 4 in my project. If you take a look at my preview by clicking here and then selecting "Liczba sztuk," you'll notice that I am facing an issue. The items within the select dropdown are gettin ...

JavaScript: Finding the full Base-URL - A Step-by-Step Guide

Is there a way to incorporate JavaScript into external files without relying on the use of base/root URLs in HTML/PHP templates? Everything is functioning properly except for the need to determine the base/root URL in an included JS file. Dilemma: I am se ...

Having trouble with the functionality of JQuery drop feature?

As I delve into implementing drag and drop functionality with JQuery, I encounter a peculiar issue. I have set up 3 'draggable' divs and corresponding 3 'droppable' divs. The intended behavior is for each draggable element to be accepte ...

Tips for expanding button width in 'react-native-swipeout' to enable swipe action on ListView row (React Native)

Currently, I am exploring how to implement the component found here: https://github.com/dancormier/react-native-swipeout My goal is to have the row swiped all the way. Is there a method to increase the button width so that it covers the entire width of th ...

Guide on setting up JSME, a chemistry portal integrated with JavaScript, within vuejs

I am looking to integrate the JSME chemistry portal into my Vuejs application. Upon the initial page load, an error is displayed: JSME initialization error: HTML id jsme_container not found. Strangely, upon refreshing the page, the error disappears. How ...

Utilize the match() method in JavaScript to target and extract a whole paragraph

I am attempting to extract an entire paragraph from a text file using JavaScript and then display it in an HTML element. Despite reading numerous posts and articles, I have been unable to find the correct regex formula. Here is an excerpt from the text fil ...

What is the best way to ensure that this jQuery window has a minimum size?

Recently, I came across a helpful jQuery demo that demonstrated how to create a popup window on my website. For those interested, the demo link can be accessed here: http://jqueryui.com/dialog/#modal-message The design of the window I am aiming to replica ...

`Filter an array retrieved from the backend in a TypeScript environment`

I have asked other questions in the past, but I received unhelpful answers. I am still looking for proper solutions. Currently, I am retrieving an array from the backend using Redux. const { movies, message } = useAppSelector(state => state.movies); ...

Creating a PHP array filled with fresh objects

As I work on developing a web-based administration frontend for my PHP application (after encountering issues with Lua and Nginx), I am facing frustration with PHP's arrays. In an attempt to initialize an array of objects, similar to what I would do ...

Is Swift affected by the same 2GB maximum serialization size issue as Java?

In programming languages like Java and other JVM based languages, it is common to serialize data into an array of bytes, especially when needing to send information over a network. But how does Swift handle data serialization for network communication? An ...

Determining the selected number option with jquery

In my HTML page, I have a set of select menus as shown below: <label>Product Details</label> <select id="PD"> <xsl:for-each select="PRODUCT_DETAILS"> <option value="{DATA0}"><xsl:value-of selec ...

Having issues with opening an exported Excel file using ExcelJS

While working on my JS project, I utilized the ExcelJS library. Everything was functioning smoothly with English characters. However, when I switched the language of my application to French and attempted to export the content as an Excel sheet, I encounte ...

When invoked, a Javascript Object comes back empty

My code snippet: const channels = fauna.paginate(q.Match(q.Index("channels"), "true")) // Query FaunaDB database for channel list => create constant called users containing results const channelList = channels.each(function (page) { ...

custom dialog box appears using ajax after successful action

Recently, I created a custom dialog/modal box with the following code: <div id="customdialog" class="modal"> <div class="modal__overlay"></div> <div class="modal__content"> <h2><strong>Hello</strong&g ...

How can I delete an item from an array when I click on a selected element using Material React Select Multiple?

I found this helpful CodeSandBox demonstration that walks through how to implement a multiple material select feature. Here is an array containing all the available options: const permissionsGroupList = [ { name: 'Sellers' }, { name: &a ...

Invoking JavaScript function from an Android Activity

I have a simple JS function that is supposed to set values of some html contents, but it doesn't seem to be working properly. Here is the code for the JS function: function SetEdits(name,email,pic,date) { document.getElementById("myPic").src=pic; doc ...

How can you link a Razor Function to a JavaScript Variable?

Trying to incorporate a Razor C# Function into a JavaScript Function has been a challenge for me. While it's simple to do in HTML, I'm encountering compilation errors when attempting it in JavaScript. I've experimented with the <text> ...

In what situations can the comma operator be beneficial?

After reading a question about the "comma operator" in expressions and exploring the MDN documentation on it, I am struggling to identify a practical scenario where it would be beneficial. Therefore, in what situations does the comma operator prove useful ...

Using Node.js to implement GET, POST, and DELETE functionalities

I have embarked on the journey of learning Node.js and I find myself in a state of confusion. Could you please guide me on how to construct effective HTTP requests for the following scenarios: 1) Retrieve all galleries from the gallerySchema using a GET ...