omi/packages/mappingjs/index.js

145 lines
3.4 KiB
JavaScript

/**
* mappingjs v2.0.0 by dntzhang
* Objects mapping for javascript. Omi MVVM's best partner.
* @method mapping
* @param {from} options
* @param {to} options
* @param {rule} options
* @return {Object} To Object
*/
var ARRAYTYPE = '[object Array]'
var OBJECTTYPE = '[object Object]'
function mapping(from, to, rule) {
var tempRule = Object.assign({}, rule)
var res = to || {}
Object.keys(from).forEach(function (key) {
var obj = from[key]
if (isArray(obj)) {
res[key] = res[key] || []
arrayMapping(obj, res[key], tempRule, key)
} else if (isObject(obj)) {
res[key] = res[key] || {}
objMapping(obj, res[key], tempRule, key)
} else {
res[key] = obj
}
})
rule && Object.keys(tempRule).forEach(function (key) {
var arr = key
.replace(/]/g, '')
.replace(/\[/g, '.')
.split('.')
if (arr.length === 1) {
res[key] = tempRule[key].call ? tempRule[key].call(from) : tempRule[key]
delete tempRule[key]
}
})
return res
}
function arrayMapping(from, to, rule, path) {
if (from.length < to.length) {
to.length = from.length
}
from.forEach(function (item, index) {
if (isArray(item)) {
to[index] = to[index] || []
arrayMapping(item, to[index], rule, path + '[' + index + ']')
} else if (isObject(item)) {
to[index] = objMapping(item, to[index], rule, path + '[' + index + ']')
} else {
to[index] = item
}
})
rule && Object.keys(rule).forEach(function (key) {
var arr = key
.replace(/]/g, '')
.replace(/\[/g, '.')
.split('.')
var pathArr = path
.replace(/]/g, '')
.replace(/\[/g, '.')
.split('.')
var dl = arr.length - pathArr.length
if (dl === 1 && equalArr(arr, pathArr)) {
to[arr[arr.length - 1]] = rule[key].call ? rule[key].call(from) : rule[key]
delete rule[key]
}
})
}
function objMapping(from, to, rule, path) {
var res = to || {}
Object.keys(from).forEach(function (key) {
var obj = from[key]
if (isArray(obj)) {
res[key] = res[key] || []
arrayMapping(obj, res[key], rule, path + '.' + key)
} else if (isObject(obj)) {
res[key] = res[key] || {}
objMapping(obj, res[key], rule, path + '.' + key)
} else {
res[key] = obj
}
})
rule && Object.keys(rule).forEach(function (key) {
var arr = key
.replace(/]/g, '')
.replace(/\[/g, '.')
.split('.')
var pathArr = path
.replace(/]/g, '')
.replace(/\[/g, '.')
.split('.')
if (arr.length - pathArr.length === 1 && equalArr(arr, pathArr)) {
res[arr[arr.length - 1]] = rule[key].call ? rule[key].call(from) : rule[key]
if (arr.indexOf('*') === -1) {
delete rule[key]
}
}
})
return res
}
function equalArr(arrA, arrB) {
var i = 0, len = arrB.length
for (; i < len; i++) {
if (arrA[i] !== arrB[i] && !(arrA[i] === '*' && !isNaN(Number(arrB[i])))) {
return false
}
}
return true
}
function isArray(obj) {
return Object.prototype.toString.call(obj) === ARRAYTYPE
}
function isObject(obj) {
return Object.prototype.toString.call(obj) === OBJECTTYPE
}
//Compatible with older versions
mapping.auto = mapping
if (typeof exports == "object") {
module.exports = mapping
} else if (typeof define == "function" && define.amd) {
define([], function () { return mapping })
} else {
window.mapping = mapping
}