jeudi 12 novembre 2015

Traversing a recursive relations matrix in javascript

There are lot of elements (expressed as checkboxes) with some different relations. For example:

  • A needs B
  • A needs C
  • A can't be combined with D
  • B can't be combined with E
  • D needs E
  • C needs F
  • F can't be combined with G

So if someone activates checkbox A, the checkboxes B and C need to be activated, too, while checkbox D needs to be disabled. Since A needs B and B can't be combined with E, checkbox E needs to be disabled, too. Since C needs F, F needs to be activated. And since F can't be combined with G, G needs to be deactivated as well.

And the other way round: If someone activates E, then B needs to be deactivated, since B can't be combined with E. But D doesn't need to be activated, because D needs E while E doesn't need D necessarily.

The big questions are now:

  1. How to ideally express the relations in javascript
  2. How to check all the relations with javascript if someone activates a checkbox.

The problem is the recursion. Every action leads to more actions which lead (possibly) to even more actions.

Current definitions of the relations (can be changed):

var relations = {
  'A': {
    'B': 'needed',
    'C': 'needed',
    'D': 'prohibited'
  },
  'B': {
    'E': 'prohibited'
  },
  'D': {
    'E': 'needed'
  },
  'C': {
    'F': 'needed'
  },
  'F': {
    'G': 'prohibited'
  }
}

Current theoretical approach:

Assumed a click on "A":

foreach (relations['A'] as related, relation) {
  if (relation === 'needed') {
    // take action
    activateRelated(related);
  } else if (relation === 'prohibited') {
    // take action
    disableRelated(related);
  }
}

But that's only the first iteration. Theoretically this could be a function which calls itself recursively after each action is taken. But on, let's say 300 Elements with a lot of relations, it loops infinite. Well, it works fine if one action is taken, one checkbox is activated. In a more realistic scenario, there are 30 to 50 % of the checkboxes active and the checking of the relations needs to go the whole way up and down.

Second problem is: if the user disables the checkbox A again, all relations need to be checked again - for all still active checkboxes, too.




Aucun commentaire:

Enregistrer un commentaire