我的应用程序从各种源系统接收数据。数据性质相同但结构不同。我需要统一结构并将它们保存到公共存储库中。
我现在正在做的事情如下:
定义传入对象和输出对象之间的结构映射。例如,对于源对象,例如:
{id:'123', message:'hi', from:{id:'user1', name:'John'}},
其映射对象如下:
var map = {_id:'id', message:'text', 'from.id':'by.id', 'from.name':'by.name'};
定义如下函数:
function setSubFieldValue(obj, field, value) {
if(field && obj && value) {
var i = field.indexOf('\.');
if( i > 0) {
var p = field.slice(0, i);
if(!obj[p]) obj[p] = {};
setSubFieldValue(obj[p], field.slice(i+1), value)
} else obj[field] = value;
}
}
function getSubFieldValue(obj, field) {
if(field) {
var i = field.indexOf('\.');
if (i > 0) {
var p = field.slice(0, i);
if(obj[p]) {
var v = field.slice(i+1);
return getSubFieldValue(obj[p], v);
}
} else return obj[field];
}
}
function mapObject (srcObj, fieldMap) {
var obj = {};
Object.keys(fieldMap).forEach(function(k) {
var v = getSubFieldValue(srcObj, k);
if(v) setSubFieldValue(obj, fieldMap[k], v);
});
return obj;
};
代码在大多数情况下都有效,但有一些缺点:
不支持数组中对象的结构映射。例如,
{arrayproperty:[{a:1, b:2}, {a:2, b:3}]}
上面的代码不允许我将这个arrayproperty映射到目标对象中的不同结构,例如:
{newfield:[{field_a:1, field_b:2}, {field_a:2, field_b:3}]}
或
{newfield_a_0:1, newfield_b_0:2, newfield_a_1:2, newfield_b_1:3}
使用递归调用并且执行效果不佳。
我想知道是否有人有类似的需求和现有库的一些想法来优雅地执行这样的任务。