[removed] Determine unknown array length and map dynamically

后端 未结 5 740
深忆病人
深忆病人 2021-02-08 11:01

Going to do my best at explaining what I am trying to do.

I have two models, mine and an api response I am receiving. When the items api response comes in, I need to map

5条回答
  •  攒了一身酷
    2021-02-08 11:19

    (old solution: https://jsfiddle.net/d7by0ywy/):

    Here is my new generalized solution when you know the two objects to process in advance (called inp and out here). If you don't know them in advance you can use the trick in the old solution to assign the objects on both sides of = to inp and out (https://jsfiddle.net/uxdney3L/3/).

    Restrictions: There has to be the same amount of arrays on both sides and an array has to contain objects. Othewise it would be ambiguous, you would have to come up with a better grammar to express rules (or why don't you have functions instead of rules?) if you want it to be more sophisticated.

    Example of ambiguity: out.items[].sku=inp[].skus[].num Do you assign an array of the values of num to sku or do you assign an array of objects with the num property?

    Data:

    rules = [
      'out.items[].name=inp[].name',
      'out.items[].sku[].num=inp[].skus[].num'
    ];
    
    inp = [{
        'name': 'Hammer',
        'skus':[{'num':'12345qwert','test':'ignore'}]
      },{
        'name': 'Bike',
        'skus':[{'num':'asdfghhj'},{'num':'zxcvbn'}]
      },{
        'name': 'Fork',
        'skus':[{'num':'0987dfgh'}]
    }];
    

    Program:

    function process() {
      if (typeof out == 'undefined') {
        out = {};
      }
      var j, r;
      for (j = 0; j < rules.length; j++) {
        r = rules[j].split('=');
        if (r.length != 2) {
          console.log('invalid rule: symbol "=" is expected exactly once');
        } else if (r[0].substr(0, 3) != 'out' || r[1].substr(0, 3) != 'inp') {
          console.log('invalid rule: expected "inp...=out..."');
        } else {
          processRule(r[0].substr(3).split('[]'), r[1].substr(3).split('[]'), 0, inp, out);
        }
      }
    }
    
    function processRule(l, r, n, i, o) { // left, right, index, in, out
      var t = r[n].split('.');
      for (var j = 0; j < t.length; j++) {
        if (t[j] != '') {
          i = i[t[j]];
        }
      }
      t = l[n].split('.');
      if (n < l.length - 1) {
        for (j = 0; j < t.length - 1; j++) {
          if (t[j] != '') {
            if (typeof o[t[j]] == 'undefined') {
              o[t[j]] = {};
            }
            o = o[t[j]];
          }
        }
        if (typeof o[t[j]] == 'undefined') {
          o[t[j]] = [];
        }
        o = o[t[j]];
        for (j = 0; j < i.length; j++) {
          if (typeof o[j] == 'undefined') {
              o[j] = {};
          }
          processRule(l, r, n + 1, i[j], o[j]);
        }
      } else {
        for (j = 0; j < t.length - 1; j++) {
          if (t[j] != '') {
            if (typeof o[t[j]] == 'undefined') {
              o[t[j]] = {};
            }
            o = o[t[j]];
          }
        }
        o[t[j]] = i;
      }
    }
    
    process();
    console.log(out);
    

提交回复
热议问题