简体   繁体   中英

Adding new objects of objects as arrays to an array

I've being scratching my day all day long to figure this out. New to javascript I need to make a WebApp using GAS for my team and I'm stuck in constructing my objects / arrays.

I have 2 data sources (google sheets). The first data source is a classic 2D array called dbProject which gives following structure when consoled out: {{…},{…},{…},{…},…}. project[0] for example returns {id: “id0”, projectCreatedBy: “fred”} .

Each of these projects has a least one phase minimum, but can have more. Each phase is structured similarly. In this example, a phase contains logistics and team information.

The second datasource dbPhase records project events relevant to 1 project's phase, such as adding a new phase to a project, adding team members or logistic info to a phase, etc… This data source is less structured then the first one and is similar to this (sorry for the bad formatting):

Id* % projectId % phaseId % typeOfEvent % pty1 % pty2 % pty3 % pty4

0 % 0 % 0 % phase % title00 % aDate00 % bDate00 % status0

1 % 0 % 0 % team % fred % mng % fred@ % empty % empty

2 % 0 % 0 % team % nick % wkr % nick@ % empty % empty

3 % 1 % 0 % phase % title10 % aDate10 % bDate10 % status0

4 % 1 % 0 % logistics % ny % US % NA % empty % empty

5 % 1 % 1 % phase % title11 % date11 % date11 % status0

6 % 0 % 1 % logistics % par % FR % EU % empty % empty

7 % 1 % 1 % team % mike % hr % mike@ % empty % empty

The data is being added to the table on a time basis (most recent event on last line), meaning that it cannot be sorted to rearrange it. Each line representing an event for a given phase of a given project, I've decided to structure this by creating an object for each 'typeOfEvent' code. My objects are coded as follow:

function phase(){
this.title = ‘ ’ ;
this.aDate = ‘ ’ ;
this.bDate = ‘ ’ ;
this.status = ‘ ’ ;
}


function logistics (){
phase.call(this);
    this.address = ‘ ’;
    this.city = ‘ ’;
    this.continent = ‘ ’;
}
logistics.prototype = Object.create(phase.prototype);
logistics.prototype.constructor = logistics;


function team(){
    phase.call(this);
    this.name = ‘ ’;
    this.role = ‘ ’;
this.email = ‘ ’;
}
team.prototype = Object.create(project.prototype);
team.prototype.constructor = team;

Inside a dbPhase.map() , I'm reading the typeOfEvent code and call dynamically the suitable object and property (one of the above), and then 'add' it to dbProject as follow:

dbPhase.map(function (row){

     //oObject is one of the above structure
     eval("var myObject = new " + oObject);

     for (var property in myObject) {
              eval('myObject.' + property + " = row[" + property + "]");  
     };

     dbProject[idProject]][typeOfEvent] = myObject

}

This runs ok as long as the structured objects don't come to add up, in which case they override the previous ones (for example id* 2 and 3: adding typeOfEvent for same project/phase patern. This will only keep the info of id* 3; id* 3 and 5: adding a new phase. Again this will only retain info from id*5; …).

My query: I wish to have a structure like this:

dbProjects(idProject).phase(idPhase).typeOfEvent.property?

ex: dbProjects(0).phase(1).logistic.pt1 to return “ny” ex: dbProjects(0).phase(0).team.pt2 to return an array of {fred@;nick@}

I've been using javascript for a month only now and don't yet master all differences between Arrays, Objects, etc... Been trying various things all day long (push, assign, brackets, parenthesis, ...) and desperately searching on the web without success (perhaps not using the correct wording). I've been looking at following posts as well, figuring that the answers would hide in there. I have no clue however on how arrange these solutions for my case (i keep thinking that it would be much easier if dbPhase table could be sorted - but it can't).

Angular2, Typescript: Add an object to an object array of an object array of an object

Add new object to another object's object

I could perhaps make quick and dirty loops and sortings to dynamically push the results? But ideally I would rather like a clean code. Your help would be more than welcome. Thanks in advance for your tips.

based on

dbProjects(idProject).phase(idPhase).typeOfEvent.property

It seems you want to keep it as nested objects rather than add an inner array?

So dbProject would appear as

const dbProject = {
  "id0": {
    phase: {}, 
    logistics: {}, 
    team: {}
  },
  "id1": {
    phase: {}, 
    logistics: {}, 
    team: {}
  },
  ...
}

In that case

dbProject[idProject]][typeOfEvent] = myObject

should be rewritten as

//first line not needed if hard coded as default
if(!dbProject[idProject]][typeOfEvent]) dbProject[idProject]][typeOfEvent] = {};
dbProject[idProject]][typeOfEvent][yourKey] = myObject

yourKey being how you want to distinguish that specific log from others of the same type. Does each new log in the second datasource have a unique id (one that refers to the log, not the project id)?. That would be a good key to use, otherwise, if you are just adding numerical keys, it would make more sense to use an array and rewrite as

//first line not needed if hard coded as default
if(!dbProject[idProject]][typeOfEvent]) dbProject[idProject]][typeOfEvent] = [];
dbProject[idProject]][typeOfEvent].push(myObject);

The resulting dbProject now looking like

const dbProject = {
  "id0": {
    phase: [], 
    logistics: [], 
    team: []
  },
  "id1": {
    phase: [], 
    logistics: [], 
    team: []
  },
  ...
}

and each log accessed as

dbProject[idProject][typeOfEvent][index]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM