Tips for organizing array objects into groups

I have a code snippet that looks like this: I am trying to figure out the best approach for this. I have a group:
data

[
  {
     "date": "16/04/2020",
     "count": 0,
     "name": "A"
  },
  {
     "date": "16/04/2020",
     "count": 1,
     "name": "B"
  },
  {
     "date": "17/04/2020",
     "count": 0,
     "name": "B"
  }                     
  //...More.....
]
          
Answer
{
    "date": "04/2020",
    "symtom": {
        "data": [
            {
                "date": "16/04/2020",
                "data": [
                    {
                        "name": "A",
                        "count": [
                            {
                                "date": "16/04/2020",
                                "count": 0,
                                "name": "A"
                            }
                        ]
                    },
{
                        "name": "B",
                        "count": [
                            {
                                "date": "16/04/2020",
                                "count": 1,
                                "name": "B"
                            }
                        ]
                    },
                    //...More.....
                ]
            },
            {
                "date": "17/04/2020",
                "data": [
                    {
                        "name": "B",
                        "count": [
                            {
                                "date": "17/04/2020",
                                "count": 0,
                                "name": "B"
                            }
                        ]
                    },
                    //...More.....
                ]
            }
        ]
    }
}

Is there a way to fix the code and get the desired output?
Code :

const items = [
  {
    tab: 'Results',
    section: '2017',
    title: 'Full year Results',
    description: 'Something here',
  },
    {
    tab: 'Results',
    section: '2017',
    title: 'Half year Results',
    description: 'Something here',
  },
    {
    tab: 'Reports',
    section: 'Marketing',
    title: 'First Report',
    description: 'Something here',
  }
];

function groupAndMap(items, itemKey, childKey, predic){
    return _.map(_.groupBy(items,itemKey), (obj,key) => ({
        [itemKey]: key,
        [childKey]: (predic && predic(obj)) || obj
    }));
}

var result = groupAndMap(items,"tab","sections", 
                   arr => groupAndMap(arr,"section", "items"));


console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

Reference : Group array of object nesting some of the keys with specific names


Here is how I would prefer the answer to look like (Answer) :

{
    "date": "04/2020",
    "symtom": {
        "data": [
            {
                "date": "16/04/2020",
                "data": [
                    {
                        "name": "A",
                        "count":  0,
                    },
                    {
                        "name": "B",
                        "count":  1,
                    },
                    //...More.....
                ]
            },
            {
                "date": "17/04/2020",
                "data": [
                    {
                        "name": "B",
                        "count":0,
                    },
                    //...More.....
                ]
            }
        ]
    }
}
Thanks!

Answer №1

As a beginner, it seems like you are aiming for system.data.data to consist of an array of objects with the keys name:str and count:number. However, it appears that the entire object is being applied into count, resulting in something like count:{name:A, count:0,date:etc}.

I'm having trouble understanding your function that separates the data, but all you need to do is make sure that when count is sent, the object references just use dot notation like object.count to access the number instead of the entire object. This way, you'll achieve the desired outcome. I hope this clarifies things for you.

Answer №2

To streamline the process, I suggest utilizing a helper function called groupBy, which is inspired by the API from Ramda (I am one of its authors). This function takes an object mapping function that assigns a key value to each element and then groups the elements based on those keys into an object with arrays of the original elements.

In this scenario, we will apply the groupBy function twice - first to group the data by month and then within those results, group it by day. The additional code in the transform function is for formatting the output as desired.

const groupBy = (fn) => (xs) => 
  xs.reduce((a, x) => ({...a, [fn(x)]: [...(a[fn(x)] || []), x]}), {})

const transform = (data) => 
  Object.entries(groupBy(({date}) => date.slice(3))(data))     // group by month
    .map(([date, data]) => ({
      date, 
      symtom: {
        data: Object.entries(groupBy(({date}) => date)(data))  // group by day
              .map(([date, data]) => ({
                date, 
                data: data.map(({date, ...rest}) => ({...rest})) // remove date property
              }))
      }
    }))

const data = [{date: "16/04/2020", count: 0, name: "A"}, {date: "16/04/2020", count: 1, name: "B"}, {date: "17/04/2020", count: 0, name: "B"}, {date: "03/05/2020", count: 0, name: "C"}];

console.log(
  transform(data)
)
.as-console-wrapper {min-height: 100% !important; top: 0}

If you require running this code in an environment without Object.entries, you can easily create a shim for it.

Answer №3

If you want to optimize the array by reducing nesting levels, you can create separate functions for each nested group and apply them in a cascading manner.

var data = [{ date: "16/04/2020", count: 0, name: "A" }, { date: "16/04/2020", count: 1, name: "B" }, { date: "17/04/2020", count: 0, name: "B" }],
    groups = [
        (o, p) => {
            var date = o.date.slice(3),
                temp = p.find(q => q.date === date);
            if (!temp) p.push(temp = { date, symptom: { data: [] } });
            return temp.symptom.data;
        },
        ({ date }, p) => {
            var temp = p.find(q => q.date === date);
            if (!temp) p.push(temp = { date, data: [] });
            return temp.data;
        },
        ({ date, ...o }, p) => p.push(o)
    ],
    result = data.reduce((r, o) => {
        groups.reduce((p, fn) => fn(o, p), r);
        return r;
    }, []);

console.log(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

I am leveraging AngularJS to display a modal window with Bootstrap and Spring servlet integration

In my project, I am utilizing AngularJS to display multiple pages. One of these pages contains a smart-table where I showcase the details of "users". When I wish to edit one of the users, I aim to display the edit page as a popup window. Below is an excer ...

Is there a way to use Javascript to verify if a window is fully open?

Is there a way to detect the complete opening of a window using JavaScript? // code1 is not functioning $(window).resize(function() { ... }); // code2 is not working window.onresize = function(event) { ... } I am ...

Assign the variable of one function to another function

I have a collection of buttons with usernames as values (such as jason, chan, brad, etc.). When a user clicks on a button, it is moved to a specific div. For example: <input type="button" onClick="nano();" id="name1" class="names" name="jason" value=" ...

What is the best way to display a border around text in an HTML element when the mouse hovers over it?

I am currently developing a Browser Helper Object (BHO) for Internet Explorer that involves searching for specific words on a web page and encasing those words in an HTML tag for styling purposes. While I have code in place that allows me to change the st ...

Uncovering the secrets of accessing req.body through expressjs

I'm having trouble accessing the body when receiving an expressjs request Here is my main server.js file: app.use(express.urlencoded({extended: true})); app.use(express.json()); app.use(router); And this is my router.js file: ...

The fixed method in JavaScript is a handy tool for converting

Is it possible to implement the toFixed() method only when the input strings exceed 12 characters in length? If not, I would like the input to display normally, resembling a standard calculator app. I have experimented with a maximum character method, but ...

Tips for configuring jQtree to initially display the tree structure from the HTML source

Up to this point, I have utilized jQuery TreeView for the navigation menus on my website. However, as the main navigation menu has grown significantly in size (40869 bytes out of 67054 bytes), I am seeking a way to streamline it by using AJAX calls to fetc ...

What is the importance of having Actions and Reducers in Redux?

I am trying to grasp the reasoning behind the design of Redux. For instance, let's consider a scenario where I have a store with a list of todos. If the store is represented as an object like this: {1: todo1, 2: todo2, 3: todo3, ...}* And we enca ...

Currently, I am experiencing difficulties with two specific aspects of the website I am working on - the hamburger menu and the slideshow feature

I'm having trouble with the menu on my website. It's not functioning as expected - the dropdown feature isn't working, and two items are not staying in the correct position under the parent ul despite attempts to position them using CSS. Add ...

Searching for a specific substring within a string using pointers in the C programming language

I am struggling to create a function that returns a pointer to a substring within a string without using integers or array indexing. Below is the code I have so far, but I am having trouble getting it to work properly. /* * Return a pointer to the firs ...

Is there a way to deactivate the onClick event when the dropdown placeholder is chosen?

I have experimented with different methods to prevent the onClick event when selecting either placeholder, but I have not been successful. Here is my current code: <div class="choosesign"> <div class="zodiacs"> < ...

Update your Selenium WebDriver Manager using npm

When attempting to update the selenium webdriver using the "webdriver-manager", an error occurred: Error: Got error Error: read ECONNRESET from https://selenium-release.storage.googleapis.com/2.48/selenium-server-standalone-2.48.2.jar Error: Got error Err ...

Should I write out the typescript .d.ts file by hand or generate it automatically

When using Typescript, you can utilize the "declaration": true" option in tsconfig to automatically generate d.ts files from your existing Typescript code. Although they may not be as concise as manually written ones, I am curious if there is any downside ...

What steps should I take to fix the TypeScript Compiler issue "Global member 'NodeJS' has no exported namespace 'Global'?"

QUERY: What steps should I take to fix the Typescript Compiler (tsc) error stating "Namespace 'NodeJS' has no exported member 'Global'"? Upon executing tsc, this particular error unexpectedly appeared in a project that is considered "l ...

combine and refresh identical items within an array

Currently, I am in the process of creating a prototype for an item-list and a shopping-cart. Both components function as standalone entities but are connected through a vuex-store. The item-list contains various elements that can be added to the shopping-c ...

What steps can I take to avoid unnecessary re-rendering of a variable that is not utilized in the HTML of my vue.js component?

I am currently in the process of replicating a real-life example of my code. In the actual code, this line represents a component that will continuously fetch an endpoint every few seconds, retrieving a random array of length "n", encapsulated wi ...

Is there a way to transfer HTML code from a textarea to CKEDITOR for setData?

My goal is to retrieve data from a textarea element and use it as setData for CKEDITOR. However, instead of receiving the HTML code, I am only getting the code as a string, which is not rendering properly as HTML. Here's the code snippet: CKEDITOR.re ...

Clicking does not trigger scrollIntoView to work properly

I'm facing an issue with a button that is supposed to scroll the page down to a specific div when clicked. I implemented a scrollIntoView function in JavaScript and attached it to the button using onClick. Although the onClick event is functioning as ...

Tutorial on how to update a specific value in an array of objects using setState on click event

I need to toggle the active class on click, setting it to a local state and changing all other objects in the state to inactive. const [jobType, setJobType] = useState([ { "class": "active", "type& ...

What is the best way to store objects containing extensive binary data along with additional values?

I'm currently working on saving a JavaScript object that includes binary data along with other values. I want the output to resemble the following: { "value":"xyz", "file1":"[FileContent]", "file2&quo ...