Javascript:确定未知数组长度并动态映射

前端之家收集整理的这篇文章主要介绍了Javascript:确定未知数组长度并动态映射前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
尽力解释我正在做的事情.

我有两个模型,我和我收到的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));
原文链接:https://www.f2er.com/js/152263.html

猜你在找的JavaScript相关文章