0

I started learning JS, especially Node.js, around 5-6 months ago, I worked a lot with Discord.js library and have knowledge of other programming languages.

I want to create a kind of datastore using Map(), before I only created arrays of objects, Discord.js had a bunch of maps in use and it was a pleasure to use them.

My new goal is to create a little app using Electron, I need to save users and program lists in maps, for persistence I want to save them as JSON, if it's possible, here are some example data from my pre-created JSON user file:

"user": [
    {
        "name": "David",
        "currentProgram": "program1",
        "currentPhase": "C",
        "workout": [
            {
                "name": "Workoutname",
                "load": "10", 
                "units": "kg"
            }
        ]
    },
    {
        "name": "Markus",
        "currentProgram": "program2",
        "currentPhase": "A",
        "workout": []
    }
]

program file:

"program": [
    {
        "name": "program1",
        "phases": [
            {
                "name": "A",
                "cycles": [
                    {
                        "name": "day 1",
                        "exercises": [
                            {
                                "name": "workout1",
                                "set": 4,
                                "repetitions": 8
                            },
                            {
                                "name": "workout2",
                                "set": 4,
                                "repetitions": 8
                            }
                        ]
                    }
                ]
            }
        ]
    }
]

My goal is to do something like this:

var user = require('./user.json');

user.get("David").currentProgram = "program2";
user.get("David").currentPhase = "A";

var phase = program.get("program1").phases.get("A")

console.log(user.get("David"));

Instead of using an array like shown in the JSON file, I would create a Map().

I was searching for some information how to create a map the best way in my case. If anyone has good how to's for learning js, especially Map() I would appreciate that. The only thing I found is array.map or google maps but that differs from Map().

Another goal is the separate the code into different files so that I have a sperate file with the construction of each map.

Thanks a lot!

2 Answers 2

1

A small helper to create a Map:

 function toMap(array, prop){
   const map = new Map();
   for(const el of array) map.set(el[prop], el);
   return map;
}

Usable like this:

 const users = JSON.parse(require("fs").readFileSync('./user.json')).user;
 users.byId = toMap(users, "name");

 console.log( users.byId.get("jonas"));
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the function, is it possible to create a map in map? Because as shown above, I have the program with their names, each program has multiple phases and each phase has multiple cycles and also each cycle has a bunch of exercises (don't necessary need a map of exercises).
1

It doesn't seem like you really need a Map for this. Since your indexes are strings, an ordinary object would do.

You can define a generic function for indexing an array:

const indexBy = (prop, arr) => arr.reduce(
    (idx, el) => { idx[el[prop]] = el; return idx; },
    {}
);

And then all you need to to to build your user map is:

let userMap = indexBy('name', userArray);

After which you can access your users like this:

userMap['David'].currentProgram = "Program 2";

To re-obtain your array for serialization, you can do:

let updatedUserArray = Object.values(userMap);

Runnable example:

const indexBy = (prop, arr) => arr.reduce(
  (idx, el) => {
    idx[el[prop]] = el;
    return idx;
  }, {}
);

// sample data
let userArray = [{
    "name": "David",
    "currentProgram": "program1",
    "currentPhase": "C",
    "workout": [{
      "name": "Workoutname",
      "load": "10",
      "units": "kg"
    }]
  },
  {
    "name": "Markus",
    "currentProgram": "program2",
    "currentPhase": "A",
    "workout": []
  }
];

let userMap = indexBy('name', userArray);

userMap['David'].currentProgram = "Program 2";
console.log(userMap['David']);

2 Comments

eslint expect a function declaration for the indexBy code, I tried it to convert it to a function style but I think I did something wrong. function indexBy(prop, arr) => { arr.reduce((idx, el) => {idx[el[prop]] = el; return idx;}, {} )}; Can you also give me some description of this part? Most of them are clear to me, I read something about .reduce() but haven't used it ever.
@MarioFridrichovsky To express it as a function declaration, you need to put a return before the arr.reduce.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.