[removed] Determine unknown array length and map dynamically

后端 未结 5 743
深忆病人
深忆病人 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:25

    So you have defined a little language to define some data addressing and manipulation rules. Let's think about an approach which will allow you to say

    access(apiPath, function(value) { insert(myPath, value); }
    

    The access function finds all the required items in apiPath, then calls back to insert, which inserts them into myPath. Our job is to write functions which create the access and insert functions; or, you could say, "compile" your little language into functions we can execute.

    We will write "compilers" called make_accessor and make_inserter, as follows:

    function make_accessor(program) {
    
      return function(obj, callback) {
    
        return function do_segment(obj, segments) {
          var start    = segments.shift()             // Get first segment
          var pieces   = start.match(/(\w+)(\[\])?/); // Get name and [] pieces
          var property = pieces[1];
          var isArray  = pieces[2];                   // [] on end
          obj          = obj[property];               // drill down
    
          if (!segments.length) {                     // last segment; callback
            if (isArray) {
              return obj.forEach(callback);
            } else {
              return callback(obj);
            }
          } else {                                    // more segments; recurse
            if (isArray) {                            // array--loop over elts
              obj.forEach(function(elt) { do_segment(elt, segments.slice()); });
            } else {
              do_segment(obj, segments.slice());      // scalar--continue
            }
          }
        }(obj, program.split('.'));
      };
    }
    

    We can now make an accessor by calling make_accessor('items[].name').

    Next, let's write the inserter:

    function make_inserter(program) {
    
      return function(obj, value) {
    
        return function do_segment(obj, segments) {
          var start    = segments.shift()             // Get first segment
          var pieces   = start.match(/(\w+)(\[\])?/); // Get name and [] pieces
          var property = pieces[1];
          var isArray  = pieces[2];                   // [] on end
    
          if (segments.length) {                      // more segments
            if (!obj[property]) {
              obj[property] = isArray ? [] : {};
            }
            do_segment(obj, segments.slice());
          } else {                                    // last segment
            obj[property] = value;
          }
        }(obj, program.split('.'));
      };
    }
    

    Now, you can express your whole logic as

    access = make_accessor('items[].name');
    insert = make_inserter('outputModel.items[].uniqueName');
    
    access(apiPath, function(val) { insert(myPath, val); });
    

提交回复
热议问题