Retrieve the two latest items in a dictionary array based on their order date

I've been browsing through similar discussions, but I just can't seem to grasp the concept. The JSON data for my current item appears to be more complicated than I anticipated. Here is a snippet of the lengthy JSON data:

items = [
      {
        'name' : 'Books',
        'types':[
          {
              'name' : 'Hard Cover',
              'genres':[
                {
                  'genre' : 'Romance',

                  'added_date' : '2018-09-15',

                  'id':1
                },
                {
                  'genre' : 'Crime',

                  'added_date' : '2018-10-01',

                  'id' : 2
                }

              ],
              'cover':['pic1.png','pic2.png']
              },
              {
                'name' : 'Audio',
                'genres':[
                  {
                    'genre' : 'Memoir',

                    'added_date' : '2018-08-01',

                    'id' : 3
                  }

                ],
                'pictures':['pic3.png','pic4.png']
           },

         ]

      },

      {
        'name' : 'Videos',
        'types':[
          {
              'name' : 'English',
              'genres':[
                {
                  'genre' : 'Comedy',

                  'added_date' : '2018-10-14',

                  'id' : 12
                }

              ],
              'pictures':['pic5.png','pic6.png']
              }

         ]

      }
  ];

What I'm aiming for now is to extract the 3 most recently added items based on their "added_date" within the "genres" block. For these items, I would like to generate an array with dictionary elements containing the full path information:

   [
    {'id':7,'genre':'Romance','name':'Hard Cover','added_date':'2018-09-16','top_parent_name':'Books'},
    {'id':8,'genre':'Memoir','name':'Audio','added_date':'2018-09-15','top_parent_name':'Books'},


     ]

The goal is to identify and retrieve the latest 3 items added throughout the entire dataset based on their "added_date" field, along with relevant details. I hope this clarifies the objective.

So far, I have brainstormed some ideas, but implementing them has proven to be quite complex.

items.forEach(function(value, index, array) {
      const types: any[] = value['types'];

      types.forEach(function(value_t, index_t, array_t){
        const genres: any[] = value_model['genes'];
       //loop again to get date....

      });



  });

Answer №1

One method to consider is extracting the desired data into objects through multiple levels of mapping followed by flattening. Using Array.prototype.flatten may not be universally supported yet, so for now, reduce(concat) can be utilized.

Once the data is transformed into a flat list, sort it in descending order based on the date. Finally, retrieve the top three values:

const items = [{"name": "Books", "types": [{"cover": ["pic1.png", "pic2.png"], "genres": [{"added_date": "2018-09-15", "genre": "Romance", "id": 1}, {"added_date": "2018-10-01", "genre": "Crime", "id": 2}], "name": "Hard Cover"}, {"genres": [{"added_date": "2018-08-01", "genre": "Memoir", "id": 3}], "name": "Audio", "pictures": ["pic3.png", "pic4.png"]}]}, {"name": "Videos", "types": [{"genres": [{"added_date": "2018-10-14", "genre": "Comedy", "id": 12}], "name": "English", "pictures": ["pic5.png", "pic6.png"]}]}];

const tops = items.map(item => item.types.map(type => type.genres.map(genre => ({
  name: type.name,
  top_name: item.name,
  ...genre
})))).reduce(
  (a, b) => a.concat(b), []
).reduce(
  (a, b) => a.concat(b), []
).sort(
  (a, b) => a.added_date > b.added_date ? -1 : a.added_date < b.added_date ? 1 : 0
).slice(0, 3)

console.log(tops)

There may be some inefficiencies with these individual loops, and the sorting process might have a time complexity of O(n * log(n)), whereas a simple maximum of three parts should ideally be O(n). However, addressing these concerns becomes necessary only if they pose a bottleneck in your application.

Answer №2

If I understand your question correctly, you are looking to extract the most recent 3 items based on their date of addition and convert them into a specific format. The solution will vary based on the amount of data being processed. One approach is to create a completely flat array of the data and then sort it by date. To achieve this, you can use an array flattening utility function (I have provided one below, but using lodash is recommended if possible).

Here's an example:

const flatten = arr => arr.reduce((a, b) => a.concat(b), [])

const mapGenres = (topName, name, genres) => genres.map(genre => ({
  name,
  topName,
  ...genre
})

const result = flatten(items.map(({ name, types }) => 
  flatten(types.map(type => mapGenres(name, type.name, type.genres)))
))

result.sort((a, b) => return b.added_date.localeCompare(a.added_date))

This code is untested, but it should be relatively simple to follow. By nesting levels of flattening and mapping functions, you can achieve the desired output structure.

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

Unable to iterate over an array within a single file Vue component

I created a vue.js app utilizing single file components. In the data section, I initialized an empty array like this: data: function () { return { teamKeys: [] } }, Next, I populate this array by pushing values into it within one of my methods: ...

Error message encountered: "myData undefined while executing server in Node.js"

const express = require('express'); const app = express(); app.post('/', (req, res) => { let newData = new contact(req.body); newData.save() .then(() => { res.send("Data has been successfully saved to ...

Protractor test fails to retain variable's value

I am currently executing a protractor test to validate the existence of a record in the grid based on a specific license number. However, I have encountered an issue where the value assigned to the rowNumber variable gets lost after traversing through all ...

Exploring the Power of Chained Promise Calls

Afterwards, in the .then section, I call another promise for an HTTP request: .then(result => { this.service().then(data => {}); }); Would you say that using chained promises in this manner is correct? ...

Error: Attempting to access the 'statusCode' property of an undefined value leads to a TypeError

I tried running the following code: npm install request Here is the actual code snippet: const request = require('request'); request('http://www.google.com', function (error, response, body) { console.log(response.statusCode); }) ...

Adjusting a NodeJS module for easier integration into codebases

I have organized some functions in a file within a node module structure... Here are the files and folder structure I created: - package.json - README.md - LICENSE.md - code |_______ code.js Currently, to use these functions, I include them like th ...

Retrieving information from an API and showcasing the resulting data in a data grid

An issue arose while attempting to retrieve data from an API and passing it to a DataGrid component. Here is an example of the data returned: { data: [{ type: 'PropertyDamage', id: '100', attributes: { ident ...

"Troubleshoot: Inadequate performance of table search in node.js due

Embarking on a journey of learning here excites me. I have an insatiable appetite for new knowledge! Grateful in advance for any assistance! Presenting a concise Node.js JavaScript code snippet of 30 lines for a standard table search process. The "table" ...

Guide on inserting text within a Toggle Switch Component using React

Is there a way to insert text inside a Switch component in ReactJS? Specifically, I'm looking to add the text EN and PT within the Switch Component. I opted not to use any libraries for this. Instead, I crafted the component solely using CSS to achie ...

Retrieving a variable value set within a jQuery function from within an Angular 2 component

In the current project, I am facing a situation where I need to work around and initialize jQuery datetimepicker inside an Angular 2 application (with plans to refactor it later). However, when I assign a datetime value to a variable, I encounter a proble ...

Vue.js - when it comes to rounding off digits, I keep getting unexpected results

Currently, I am in the process of calculating my totals and I need to ensure that they are fixed to 2 decimal places. Here is a snippet of my code: this.selectedCompaniesDetails.forEach((company) => { if(company.id == p.compa ...

How can I locate a single hidden field within a div containing multiple fields?

Within one div, I have three hidden fields. How can I access and retrieve just one of these hidden fields when referencing this specific div? ...

Error: Unable to locate module: Material-UI - Please check the path and try again

Encountering this error: Error message: Failed to compile ./node_modules/@material-ui/core/Modal/Modal.js Module not found: Can't resolve '@babel/runtime/helpers/builtin/assertThisInitialized' in 'C:\Users\rifat\ ...

Error: Unexpected character U found at the beginning of the JSON data when using JSON.parse in Angular 8

Lately, I came across an issue while making changes to some parts of my previous code. The error caught my attention as it occurred when trying to pass a specific object or a part of that object in Angular 8, NodeJS with express, and mongoose. Upon checki ...

The collaboration of TypeScript and Vue in implementing index signatures resulted in the TS7053 specification

Utilizing Vue 2.6 with vue class component along with typescript. Here is the current code snippet: private validateField(fieldType: string, e: string) { this[fieldType] = e.length > 0 } An error is being thrown: Error TS7053: Element implicitly h ...

Tutorial on moving a bullet towards the cursor in Phaser 3

Currently, I am working on developing a 2D game and facing a challenge in making the bullets move towards the cursor. Here is the code snippet that I have been using: let xDist = this.game.input.mousePointer.x - this.x; let yDist = this.game.input.mousePo ...

"Troubleshooting problems with preloading images using jQuery

I've been working on a project to implement server-side image rotation using jquery and php. Everything seems to be running smoothly, except for the preloading function. When the new image is returned from the backend, it takes a couple of seconds dur ...

Enhanced assistance for optional chaining operator available in Visual Studio Code

React Native 0.56 now supports the Optional Chaining Operator with ?. Unfortunately, the latest stable version of VS Code does not recognize this syntax and displays a TypeScript validation error: [ts] Expression expected. No compile-time or eslint erro ...

Shutting down a filtered v-treeview node becomes sluggish when operating with a large number of items

My v-treeview has a node with approximately 2000 children, and I am in need of applying a filter to it. However, the current issue is that opening the node takes around 3 seconds, while closing it takes about 15 seconds, which is completely unacceptable. ...

Is there a way to assign retrieved data to the $scope.variable?

I'm relatively new to both JavaScript and Angular. I have a piece of code that fetches data from an API and successfully prints it to the console, but I'm facing issues when trying to assign this data to $scope.saveData. It seems to only work wit ...