How can I convert an Array into a Dictionary using JavaScript?

Is there a clever method (perhaps using a map function) to restructure my data object from this:

[
  {id: 1, from: "1/1/2021", to: "1/2/2022"},
  {id: 2, from: "1/3/2021", to: "1/4/2022"},
  {id: 1, from: "1/5/2021", to: "1/6/2022"},
  {id: 2, from: "1/6/2021", to: "1/7/2022"}
]

to the following format:

{
  1: [{from: "1/1/2021", to: "1/2/2022"}, {from: "1/5/2021", to: "1/6/2022"}],
  2: [{from: "1/3/2021", to: "1/4/2022"}, {from: "1/6/2021", to: "1/7/2022"}]
}

Check out the code snippet below for reference:

const res = [
  {id: 1, from: "1/1/2021", to: "1/2/2022"},
  {id: 2, from: "1/3/2021", to: "1/4/2022"},
  {id: 1, from: "1/5/2021", to: "1/6/2022"},
  {id: 2, from: "1/6/2021", to: "1/7/2022"}
]

let dict = {};
for(var i=0; i < res.length; i++) {
   dict[res[i].id] = dict[res[i].id] || [];
   dict[res[i].id].push({from:res[i].from, to:res[i].to});
}
console.log(dict);

Answer №1

To group by any property, such as id, you can implement a custom groupBy() function using Array.reduce() to transform the data into the desired object structure.

Note: In this updated version, we have excluded the specified property, in this case id, from the resulting grouped arrays.

let input = [ {id: 1, from: "1/1/2021", to: "1/2/2022"}, {id: 2, from: "1/3/2021", to: "1/4/2022"}, {id: 1, from: "1/5/2021", to: "1/6/2022"}, {id: 2, from: "1/6/2021", to: "1/7/2022"} ];

function groupBy(arr, property) {
    return arr.reduce((acc, cur) => {
        const { [property]: _, ...obj} = cur;
        acc[cur[property]] = [...(acc[cur[property]] || []), obj];
        return acc;
    }, {})
}

console.log(groupBy(input, 'id'))
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>

You also have the option to utilize lodash groupBy for this purpose, requiring minimal code:

let input = [ {id: 1, from: "1/1/2021", to: "1/2/2022"}, {id: 2, from: "1/3/2021", to: "1/4/2022"}, {id: 1, from: "1/5/2021", to: "1/6/2022"}, {id: 2, from: "1/6/2021", to: "1/7/2022"} ];

console.log('groupBy (lodash):', _.groupBy(input, 'id'));
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js" integrity="sha512-90vH1Z83AJY9DmlWa8WkjkV79yfS2n2Oxhsi2dZbIv0nC4E6m5AbH8Nh156kkM7JePmqD6tcZsfad1ueoaovww==" crossorigin="anonymous"></script>

Additionally, you can leverage reduce with a Map object for grouping purposes:

let input = [ {id: 1, from: "1/1/2021", to: "1/2/2022"}, {id: 2, from: "1/3/2021", to: "1/4/2022"}, {id: 1, from: "1/5/2021", to: "1/6/2022"}, {id: 2, from: "1/6/2021", to: "1/7/2022"} ];

function groupBy(arr, property) {
    return Object.fromEntries(arr.reduce((acc, cur) => { 
        return acc.set(cur[property], [...(acc.get(cur[property]) || []), cur]);
    }, new Map()))
}

console.log(groupBy(input, 'id'))
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>

Answer №2

Using Array.reduce() method can provide a solution to your issue.

const data = [
  {id: 1, from: "1/1/2021", to: "1/2/2022"},
  {id: 2, from: "1/3/2021", to: "1/4/2022"},
  {id: 1, from: "1/5/2021", to: "1/6/2022"},
  {id: 2, from: "1/6/2021", to: "1/7/2022"}
];

var result = data.reduce(function(accumulator, {id, from, to}) {
  (accumulator[id] = accumulator[id] || []).push({from, to});
  return accumulator;
}, {});

console.log(result);

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'm currently utilizing lint in my Angular 2+ project. Is there a way to arrange the constructor parameters in alphabetical order

I am struggling to organize the constructor parameters in TypeScript while using TSLINT with Angular9. I am looking for a rule similar to member-ordering that can help me sort them effectively. constructor( // Sort these private readonly router: R ...

Encountered an issue while working with npm vue-cli

Operating System: Windows 10 Node Version: v8.9.2 NPM Version: 5.5.1 I successfully installed vue-cli using NPM, but encountered an error when trying to run 'npm run dev' command. Below is the error message: npm ERR! code ELIFECYCLE npm ERR! ...

Connecting to a MongoDB or Mongoose database dynamically using Node.js

I am currently working on developing a multi-tenant application where each client will have its own dedicated database. Here is my scenario: I have created a middleware that identifies the client based on their subdomain and retrieves the necessary datab ...

Update the inputs following the filtering or searching of issues in VueJS

As a newcomer to VueJS, I find myself struggling with a particular function and lack the experience to fully grasp it. To address my confusion, I have formulated a question (which may be similar to others). For instance, I utilized the computed propert ...

Troubleshooting the issue of "Mismatched transaction number*" in MongoDB and Node.js

While trying to add data, I encountered an issue with modifying two schemas using ACID transactions in MongoDB with Node.js. Upon running the program, an error was displayed: (node:171072) UnhandledPromiseRejectionWarning: MongoError: Given transaction n ...

Tips for retrieving an element's outerHTML, innerHTML, and text content using JavaScript

I am new to the protractor framework and I have been struggling to find a way to access, using outerHTML/InnerHTML/getText(), the child elements in order to test if an <img> element is being displayed on a view. Specifically, I am working with an ng- ...

Changes made in the view of a VueJS application are not being reflected in Laravel when using

Embarking on my first journey with VueJS within a Laravel PHP framework has been quite the adventure. A new project is on the horizon, and I dove in headfirst by making various changes, such as adding new elements and altering titles. However, much to my d ...

The process of linking a JsonObject attribute to XML using MOXy

I am currently working with the following class structure: @XmlRootElement(name = "Root") class MyClass { @XmlElement(name = "Entries") JsonObject getProperty() { ... } } My goal is to generate the following XML output upon marshalling: <Roo ...

Utilize Vue.JS to showcase JSON information from an external file

Currently, I have a View.JS app that displays a conversation thread from a JSON file. The existing code appears as follows: const app = new Vue({ el: "#app", data: { messages:[ { name: "Support", message: "Hey! Welcome to suppo ...

"Encountering a Node.js error while trying to open an image for the second

My goal is to use Node to take a screenshot of the user's screen on all displays and save everything in a single image. Everything works fine when I call it for the first time, but if I try to call it a second time without restarting the server, an er ...

Utilizing Loops to Generate Unique CSS Designs on an HTML Page

View reference image ->Take a look at the reference image provided. ->In the image, a for loop is used to create box designs and displayed above. ->The goal is to change the background color and border color of all boxes using a single HTML cla ...

Best method for reusing a component in React?

Here is a simplified code featuring a reusable button component: import React from 'react' import styles from './Button.module.scss' const Button = (props) => { return ( <button type={props.type} className={styles.btn} onC ...

Enhance the parsed struct by adding a new variable called json

As I work with some static data related to a list of "Badges," my goal is to parse it using JSONDecoder. However, I encountered an issue when trying to add a new state that wasn't included in the JSON data. Adding this variable to the Badge struct led ...

Can transclusion be achieved while maintaining the directive's scope in Angular?

Can we achieve the following functionality in Angular? <div ng-controller="MainCtrl" ng-init="name='World'"> <test name="Matei">Hello {{name}}!</test> // I expect "Hello Matei" <test name="David">Hello {{name}}!&l ...

Angular 2 is not recognizing the element 'router-outlet'

I am currently utilizing universal-cli... This is how my app.node.module.ts appears: /** * This file and `main.browser.ts` are quite similar, for now! * By separating these, you can create logic, imports, etc that are "Platform" specific. * If you wis ...

What is the best way to modify an array of objects within component state?

I am currently working on updating a specific property of an object that is stored in an array. Here's a glimpse of my current state: state = { todos: [ { id: '1', title: 'first item, completed: false }, { ...

Extract objects from a nested array using a specific identifier

In order to obtain data from a nested array of objects using a specific ID, I am facing challenges. My goal is to retrieve this data so that I can utilize it in Angular Gridster 2. Although I have attempted using array.filter, I have struggled to achieve t ...

Can global scope be injected into a class instantiated in ES6, also known as a singleton?

Before I get started, I want to apologize in advance for the lengthy code that is about to follow. It may make this question seem a bit bloated, but I believe it's necessary for understanding my issue. Imagine we have a predefined MainModule: ' ...

Increasing numerical values within an array using JavaScript

My goal is to enhance the functionality of this visualization by being able to increase or decrease the nodes in the hidden layers. I have attempted to achieve this by adding the following code: I am facing difficulties in adjusting the number of hidden l ...

Using MEAN.JS to Define Query Parameters for Mongo from the Client Controller

I am currently developing an application using the MEAN stack - MongoDB, Angular, Express, and Node.js. To kickstart my project, I utilized the MEAN.JS generator to set up the initial structure of my application. The articles module within my application ...