尽力解释我正在做的事情.
我有两个模型,我和我收到的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));