尽力解释我正在做的事情.
我有两个模型,我和我收到的api回复.当项目api响应进来时,我需要将其映射到我的模型并插入所有项目.这当然很简单.回答这个问题,我需要这样做,而不知道我正在处理什么.我的代码将被传递两个字符串,我的一个模型映射路径和一个api响应映射路径.
这是两条路
var myPath = "outputModel.items[].uniqueName" var apiPath = "items[].name"
基本上为apiPath中的所有项目,推入myPath中的项目并设置为uniqueName
归结到的是,当需要映射两个项目时,或者即使它们包含一个数组或简单的字段到现场路径,我的代码也没有任何意义.他们甚至可以包含多个数组,如下所示:
********************示例*************************
var items = [ { name: "Hammer",skus:[ {num:"12345qwert"} ] },{ name: "Bike",skus:[ {num:"asdfghhj"},{num:"zxcvbn"} ] },{ name: "Fork",skus:[ {num:"0987dfgh"} ] } ] var outputModel = { storeName: "",items: [ { name: "",sku:"" } ] }; outputModel.items[].name = items[].name; outputModel.items[].sku = items[].skus[].num;
************************以上是上述的预期结果
var result = { storeName: "",items: [ { name: "Hammer",sku:"12345qwert" },{ name: "Bike",sku:"asdfghhj" },sku:"zxcvbn" },{ name: "Fork",sku:"0987dfgh" } ] };
我将给出一组要映射的每个值的路径.在上面的情况下,我被交给了两组路径,因为我映射了两个值.它必须遍历两组数组以在我的模型中创建单个数组.
问题 – 无论两个模型路径如何,我如何动态地检测数组并正确移动数据?可能?
解决方法
如在评论中提到的,输入格式没有严格的定义,很难用完美的错误处理来处理所有的角落.
这是我的冗长实现,适用于您的示例,但对于其他一些情况可能会失败:
function merge_objects(a,b) { var c = {},attr; for (attr in a) { c[attr] = a[attr]; } for (attr in b) { c[attr] = b[attr]; } return c; } var id = { inner: null,name: "id",repr: "id",type: "map",exec: function (input) { return input; } }; // set output field function f(outp,mapper) { mapper = typeof mapper !== "undefined" ? mapper : id; var repr = "f("+outp+","+mapper.repr+")"; var name = "f("+outp; return { inner: mapper,name: name,repr: repr,clone: function(mapper) { return f(outp,mapper); },exec: function (input) { var out = {}; out[outp] = mapper.exec(input); return out; } }; } // set input field function p(inp,mapper) { var repr = "p("+inp+","+mapper.repr+")"; var name = "p("+inp; return { inner: mapper,type: mapper.type,clone: function(mapper) { return p(inp,exec: function (input) { return mapper.exec(input[inp]); } }; } // process array function arr(mapper) { var repr = "arr("+mapper.repr+")"; return { inner: mapper,name: "arr",clone: function(mapper) { return arr(mapper); },exec: function (input) { var out = []; for (var i=0; i<input.length; i++) { out.push(mapper.exec(input[i])); } return out; } }; } function combine(m1,m2) { var type = (m1.type == "flatmap" || m2.type == "flatmap") ? "flatmap" : "map"; var repr = "combine("+m1.repr+","+m2.repr+")"; return { inner: null,type: type,name: "combine",exec: function (input) { var out1 = m1.exec(input); var out2 = m2.exec(input); var out,i,j; if (m1.type == "flatmap" && m2.type == "flatmap") { out = []; for (i=0; i<out1.length; i++) { for (j=0; j<out2.length; j++) { out.push(merge_objects(out1[i],out2[j])); } } return out; } if (m1.type == "flatmap" && m2.type != "flatmap") { out = []; for (i=0; i<out1.length; i++) { out.push(merge_objects(out1[i],out2)); } return out; } if (m1.type != "flatmap" && m2.type == "flatmap") { out = []; for (i=0; i<out2.length; i++) { out.push(merge_objects(out2[i],out1)); } return out; } return merge_objects(out1,out2); } }; } function flatmap(mapper) { var repr = "flatmap("+mapper.repr+")"; return { inner: mapper,type: "flatmap",name: "flatmap",clone: function(mapper) { return flatmap(mapper); },exec: function (input) { var out = []; for (var i=0; i<input.length; i++) { out.push(mapper.exec(input[i])); } return out; } }; } function split(s,t) { var i = s.indexOf(t); if (i == -1) return null; else { return [s.slice(0,i),s.slice(i+2,s.length)]; } } function compile_one(inr,outr) { inr = (inr.charAt(0) == ".") ? inr.slice(1,inr.length) : inr; outr = (outr.charAt(0) == ".") ? outr.slice(1,outr.length) : outr; var Box = split(inr,"[]"); var Box2 = split(outr,"[]"); var m,ps,fs,j; if (Box == null && Box2 == null) { // no array! m = id; ps = inr.split("."); fs = outr.split("."); for (i=0; i<fs.length; i++) { m = f(fs[i],m); } for (j=0; j<ps.length; j++) { m = p(ps[j],m); } return m; } if (Box != null && Box2 != null) { // array on both sides m = arr(compile_one(Box[1],Box2[1])); ps = Box[0].split("."); fs = Box[0].split("."); for (i=0; i<fs.length; i++) { m = f(fs[i],m); } return m; } if (Box != null && Box2 == null) { // flatmap m = flatmap(compile_one(Box[1],outr)); ps = Box[0].split("."); for (j=0; j<ps.length; j++) { m = p(ps[j],m); } return m; } return null; } function merge_rules(m1,m2) { if (m1 == null) return m2; if (m2 == null) return m1; if (m1.name == m2.name && m1.inner != null) { return m1.clone(merge_rules(m1.inner,m2.inner)); } else { return combine(m1,m2); } } var input = { store: "myStore",items: [ {name: "Hammer",skus:[{num:"12345qwert"}]},{name: "Bike",skus:[{num:"asdfghhj"},{num:"zxcvbn"}]},{name: "Fork",skus:[{num:"0987dfgh"}]} ] }; var m1 = compile_one("items[].name","items[].name"); var m2 = compile_one("items[].skus[].num","items[].sku"); var m3 = compile_one("store","storeName"); var m4 = merge_rules(m3,merge_rules(m1,m2)); var out = m4.exec(input); alert(JSON.stringify(out));