js解析php格式的表單到json物件

usher.yue發表於2017-09-08
/**
 * JsonParse
 *  Created by usher.yue.
 * User: usher.yue
 * Date: 17/9/7
 * Time: 13:50
 * 心懷教育夢-煙臺網格軟體技術有限公司
 */

class JsonConvert {
    /**
     *是否可合併 去除特殊型別和 日期型別
     * @param value
     * @returns {boolean}
     * @private
     */
    _mergeable(value) {
        var stringValue = Object.prototype.toString.call(value);
        return (!!value && typeof value === `object`) && ( stringValue !== `[object RegExp]`
            && stringValue !== `[object Date]`);
    };

    /**
     * 是否有必要合併
     * @param value
     * @param args
     * @returns {*}
     */
    _cloneIfNecessary(value, args) {
        var clone = args && args.clone === true;
        return (clone && _mergeable(value)) ? _deepMerge(Array.isArray(value) ? [] : {}, value, args) : value
    }

    /**
     * 陣列深度合併
     * @param target
     * @param source
     * @param args
     * @returns {Array.<T>|string|Blob|ArrayBuffer}
     * @private
     */
    _arrayMerge(target, source, args) {
        var destination = target.slice();
        source.forEach(function (e, i) {
            var ctx = this;
            if (typeof destination[i] === `undefined`) {
                destination[i] = ctx._cloneIfNecessary(e, args);
            } else if (ctx._mergeable(e)) {
                destination[i] = ctx._deepMerge(target[i], e, args);
            } else if (target.indexOf(e) === -1) {
                destination.push(ctx._cloneIfNecessary(e, args));
            }
        }, this);
        return destination
    }

    /**
     *深度合併物件
     * @param target
     * @param source
     * @param args
     * @returns {{}}
     * @private
     */
    _mergeObject(target, source, args) {
        var destination = {};
        var ctx = this;
        if (this._mergeable(target)) {
            Object.keys(target).forEach(function (key) {
                destination[key] = ctx._cloneIfNecessary(target[key], args);
            });
        }
        Object.keys(source).forEach(function (key) {
            if (!ctx._mergeable(source[key]) || !target[key]) {
                destination[key] = ctx._cloneIfNecessary(source[key], args);
            } else {
                destination[key] = ctx._deepMerge(target[key], source[key], args);
            }
        });
        return destination
    }

    /**
     * 深度合併, 可自定義合併函式
     * @param target
     * @param source
     * @param args
     * @returns {*}
     * @private
     */
    _deepMerge(target, source, args) {
        var sourceIsArray = Array.isArray(source);
        var targetIsArray = Array.isArray(target);
        //預設深度合併陣列
        var options = args || {arrayMerge: this._arrayMerge};
        //判斷是否是一個物件避免浪費時間
        var sourceAndTargetTypesMatch = (sourceIsArray === targetIsArray);
        if (!sourceAndTargetTypesMatch) {
            return this._cloneIfNecessary(source, args)
        } else if (sourceIsArray) {
            return (options.arrayMerge || this._arrayMerge).call(this, target, source, args)
        } else {
            return this._mergeObject(target, source, args)
        }
    }

    /**
     * 必須兩個引數
     * @param array
     * @param args
     * @returns {*}
     * @private
     */
    _merge(array, args) {
        if (!Array.isArray(array) || array.length < 2) {
            return false;
        }
        var ctx = this;
        //順序執行deep merge
        return array.reduce(function (prev, next) {
            return ctx._deepMerge(prev, next, args)
        })
    };

    /**
     * json parser
     * @param obj
     * @param keyList
     * @param deepVal
     * @returns {*}
     * @private
     */
    _parseToJson(obj, keyList, deepVal) {
        let retObj = null;
        if (!keyList) {
            let re = /([_a-zA-Z]w+|[]|[[0-9]+]|[[_a-zA-Z]w*])/g;
            let combineArr = [];
            for (var key in obj) {
                retObj = {};
                //解析key
                let matchSubKey = re[Symbol.match](key);
                let indexMatch = /^[([0-9]+)]$/.exec(matchSubKey[1]);
                let noneIndexMatch = /^[]$/.exec(matchSubKey[1]);
                let objectMatch = /^[([a-zA-Z_]w+)]$/.exec(matchSubKey[1]);
                if (indexMatch) {
                    retObj[matchSubKey[0]] = [];
                } else if (noneIndexMatch) {
                    retObj[matchSubKey[0]] = [];
                } else if (objectMatch) {
                    retObj[matchSubKey[0]] = {};
                }
                retObj[matchSubKey[0]] = this._parseToJson(null, matchSubKey.slice(1), obj[key]);
                combineArr.push(retObj);
            }
            return this._merge(combineArr);
        } else {
            if (keyList.length > 1) {
                let indexMatch = /^[([0-9]+)]$/.exec(keyList[0]);
                let noneIndexMatch = /^[]$/.exec(keyList[0]);
                let objectMatch = /^[([a-zA-Z_]w+)]$/.exec(keyList[0]);
                if (indexMatch) {
                    retObj = [];
                    retObj[indexMatch[1]] = this._parseToJson(null, keyList.slice(1), deepVal);
                } else if (noneIndexMatch) {
                    retObj = [];
                    retObj[noneIndexMatch[1]] = [];
                    retObj.push(this._parseToJson(null, keyList.slice(1), deepVal));
                } else if (objectMatch) {
                    retObj = {};
                    retObj[objectMatch[1]] = {};
                    retObj[objectMatch[1]] = this._parseToJson(null, keyList.slice(1), deepVal);
                }
            } else if (keyList.length == 1) {
                let indexMatch = /^[([0-9]+)]$/.exec(keyList[0]);
                let noneIndexMatch = /^[]$/.exec(keyList[0]);
                let objectMatch = /^[([a-zA-Z_]w+)]$/.exec(keyList[0]);
                if (indexMatch) {
                    retObj = [];
                    retObj[indexMatch[1]] = deepVal;
                } else if (noneIndexMatch) {
                    retObj = [];
                    retObj.push(deepVal);
                } else if (objectMatch) {
                    retObj[objectMatch[1]] = deepVal;
                }
            }
        }
        return retObj;
    }

    /**
     * type
     * @param o
     * @returns {*}
     * @private
     */
    _type(o) {
        return Object.prototype.toString.call(o);
    }

    /**
     * 轉換
     * @param obj
     * @returns {*}
     */
    parse(obj) {
        return this._parseToJson(obj);
    }

    /**
     * 轉換
     * @param obj
     * @returns {*}
     */
    stringify(obj) {
        return JSON.stringify(this._parseToJson(obj));
    }
}


var obj = {
    `data[0][classid][0]`: `1000150097620084286`,
    `data[0][create_time][0]`: `1504692288`,
    `data[0][kcid][0]`: `1033150427887550927`,
    `data[0][schoolid][0]`: `1033144479144228284`,
    `data[0][type][0]`: `2`,
    `data[0][uid][0]`: `1034145308280458231`,
    `data[0][zyid][0]`: `1000150235157063544`,
    `data[0][zytype][0]`: `homework-exercise`,

    `data[1][classid][0]`: `10001500976200842861`,
    `data[1][create_time][0]`: `1504692288`,
    `data[1][kcid][0]`: `1033150427887550927`,
    `data[1][schoolid][0]`: `1033144479144228284`,
    `data[1][type][0]`: `2`,
    `data[1][uid][0]`: `1034145308280458231`,
    `data[1][zyid][0]`: `1000150235157063544`,
    `data[1][zytype][0]`: `homework-exercise`,
    //
    `data[2][classid][]`: `10001500976200842861`,
    `data[2][create_time][]`: `1504692288`,
    `data[2][kcid][]`: `1033150427887550927`,
    `data[2][schoolid][]`: `1033144479144228284`,
    `data[2][type][]`: `2`,
    `data[2][uid][]`: `1034145308280458231`,
    `data[2][zyid][]`: `1000150235157063544`,
    `data[2][zytype][]`: `homework-exercise`,

    `data[3][classid][]`: `10001500976200842861`,
    `data[3][create_time][]`: `1504692288`,
    `data[3][kcid][]`: `1033150427887550927`,
    `data[3][schoolid][]`: `1033144479144228284`,
    `data[3][type][]`: `2`,
    `data[3][uid][]`: `1034145308280458231`,
    `data[3][zyid][]`: `1000150235157063544`,
    `data[3][zytype][]`: `homework-exercise`,

    `data[3][classid][]`: `10001500976200842861`,
    `data[3][create_time][]`: `1504692288`,
    `data[3][kcid][]`: `1033150427887550927`,
    `data[3][schoolid][]`: `1033144479144228284`,
    `data[3][type][]`: `2`,
    `data[3][uid][]`: `1034145308280458231`,
    `data[3][zyid][]`: `1000150235157063544`,
    `data[3][zytype][]`: `homework-exercise`
};


let json = new JsonConvert();
console.log(json.parse(obj));
console.log(json.stringify(obj))


相關文章