Nodejs JSON 对象属性名转换

Nodejs JSON 对象属性名转换

工作中,写了个有意思的函数: self.upper.dataSourceTypes = JSON.parse(msg); //加载 库类型 //数据属性转换 var dataTypes = changeJsonName({changeName:{“TypeName”:“name”,“TypeID”:“id”},objs:self.upper.dataSourceTypes}); 把对象中的"TypeName",“TypeID” 改成 name",“id” //欢迎有兴趣的朋友指正优化!!! /* *JSON 属性名转换 *参数形式:{changeName:{a:A,b:B},objs:obj} => 例子: {changeName:{“id”:“KEY”},objs:[{id:2},{id:4}]} id为2的JSON对象(数组)改变成[{KEY:2,KEY:4}] *changeName要修改的对象属性名=>{a:A,b:B},objs该对象/对象数组 */ function changeJsonName(o){ var newObj = []; if(o.hasOwnProperty(“changeName”)){ if(o.hasOwnProperty(“objs”)){ var cloneStr = JSON.stringify(o.objs); var cloneObj = JSON.parse(cloneStr); var doit = function(obj){

			if(obj.constructor  == Array){
				for(var i=0;i<obj.length;i++){
					doit(obj[i]);
				}
			}else{
				//循环该对象的属性
				for(var i in obj){
					//循环要改变的属性名
					for(var x in o.changeName){
						//如果名称相同
						if(x == i){
							obj[o.changeName[x]] = obj[i];
							delete obj[i];
						}
					}
				}
			}
		}
		doit(cloneObj);
		return cloneObj;
	}
}
return false;

}

//欢迎有兴趣的朋友指正优化!!!


10 回复

Node.js JSON 对象属性名转换

在实际开发中,我们经常需要对 JSON 数据进行处理,比如将某些属性名转换为另一种形式。下面是一个用于将 JSON 对象或数组中的特定属性名进行转换的函数示例。

函数说明

changeJsonName 函数接受一个对象作为参数,该对象包含两个属性:

  • changeName: 一个对象,键表示需要被替换的属性名,值表示替换后的属性名。
  • objs: 需要进行属性名转换的 JSON 对象或对象数组。

示例代码

function changeJsonName(o) {
    var newObj = [];

    if (o.hasOwnProperty('changeName')) {
        if (o.hasOwnProperty('objs')) {
            var cloneStr = JSON.stringify(o.objs);
            var cloneObj = JSON.parse(cloneStr);

            var doit = function (obj) {
                if (obj.constructor == Array) {
                    for (var i = 0; i < obj.length; i++) {
                        doit(obj[i]);
                    }
                } else {
                    // 循环该对象的属性
                    for (var i in obj) {
                        // 循环要改变的属性名
                        for (var x in o.changeName) {
                            // 如果名称相同
                            if (x === i) {
                                obj[o.changeName[x]] = obj[i];
                                delete obj[i];
                            }
                        }
                    }
                }
            }

            doit(cloneObj);
            return cloneObj;
        }
    }
    return false;
}

// 使用示例
const msg = '{"TypeName":"TypeA","TypeID":1}';
const dataSourceTypes = JSON.parse(msg);

const result = changeJsonName({
    changeName: {"TypeName": "name", "TypeID": "id"},
    objs: dataSourceTypes
});

console.log(result); // 输出: { name: 'TypeA', id: 1 }

解释

  1. 函数定义:

    • changeJsonName 接受一个对象 o,该对象包含 changeNameobjs 两个属性。
  2. 克隆数据:

    • 使用 JSON.stringifyJSON.parse 方法克隆输入的数据,以避免直接修改原始数据。
  3. 递归处理:

    • doit 是一个递归函数,用于遍历对象或数组,并根据 changeName 的规则修改属性名。
    • 如果当前对象是数组,则递归处理每个元素。
    • 如果当前对象是普通对象,则遍历其所有属性,检查是否需要修改属性名。
  4. 属性名替换:

    • 如果发现某个属性名需要替换,则创建新的属性并删除旧的属性。
  5. 返回结果:

    • 最终返回处理后的对象或对象数组。

通过这种方式,我们可以方便地对 JSON 数据进行属性名转换,而不需要手动处理每个对象。


代码高亮重新编辑一下吧…… 最好给个使用前、使用后的示例

var _ = require('lodash');

function changeKeyNames(obj, namesMap) {
  return _.transform(obj, function(result, value, key) {
    result[namesMap[key] || key] = value;
  });
}

changeKeyNames({'a': 1, 'b': 2, 'c': 3}, {'a': 'A', 'b': 'B'});
// → {'A': 1, 'B': 2, 'c': 3}

引用 ravenwang的数据 {‘a’: 1, ‘b’: 2, ‘c’: 3} 需要转换成 {‘A’: 1, ‘B’: 2, ‘c’: 3} 那么 就是 a=>A,b=>B,c不用变 changeJsonName({ changeName:{“a”:“A”,“b”:“B”}, objs:{‘a’: 1, ‘b’: 2, ‘c’: 3} });

写这么神奇的函数干啥:( 用来做数据重构么?

如果json结构很复杂,你的函数估计就没用鸟:)

在某些时候会用到,比如匹配在一个公用插件用的数据结构… 主要觉着有意思

我写的changeKeyNames是一个实现同样功能的函数…

const transformModel = (object = {}, keymap = {}) => {
  if (typeof object !== 'object' || object === null) return object

  if (Array.isArray(object)) {
    return object.map(value => transformModel(value, keymap))
  }

  return Object.keys(object).reduce((result, curkey) => {
    if (keymap[curkey]) {
      const { value, children } = keymap[curkey]

      result[value] = transformModel(object[curkey], children)
    } else {
      result[curkey] = object[curkey]
    }

    return result
  }, {})
}

const testKeyMap = {
  name: { value: 'title' },
  detail: {
    value: 'infos',
    children: {
      content: { value: 'body' },
      viewCount: { value: 'vc' }
    }
  },
  imgs: {
    value: 'images',
    children: {
      text: { value: 'name' }
    }
  }
}

const testOriginObj = {
  name: '名称',
  detail: {
    content: '内容',
    viewCount: '浏览量',
    other: '未定义项'
  },
  imgs: [
    { text: '图片1' },
    '图片2'
  ],
  other: '未定义项'
}

console.log(testOriginObj)
console.log(transformModel(testOriginObj, testKeyMap))

在处理 JSON 对象属性名转换时,上述代码有一些逻辑上的问题。例如,数组中的对象可能被错误地覆盖或删除。下面是改进后的示例代码:

function changeJsonName(options) {
    const { changeName, objs } = options;

    // 检查输入是否正确
    if (!changeName || !objs) return null;

    // 如果输入是单个对象,则包装成数组以简化处理
    const isSingleObject = !Array.isArray(objs);
    const objects = isSingleObject ? [objs] : objs;

    const transformedObjects = objects.map(obj => {
        const newObj = {};

        for (const key in obj) {
            if (changeName[key]) {
                newObj[changeName[key]] = obj[key];
            } else {
                newObj[key] = obj[key];
            }
        }

        return newObj;
    });

    // 如果输入是单个对象,返回单个对象;否则返回整个数组
    return isSingleObject ? transformedObjects[0] : transformedObjects;
}

// 使用示例
const dataSourceTypes = [
    {"TypeName": "Type1", "TypeID": 1},
    {"TypeName": "Type2", "TypeID": 2}
];

const convertedTypes = changeJsonName({
    changeName: {"TypeName": "name", "TypeID": "id"},
    objs: dataSourceTypes
});

console.log(convertedTypes);

此函数接收一个配置对象作为参数,该对象包含两个属性:changeNameobjschangeName 是一个映射对象,表示原始属性名与新属性名之间的映射关系。objs 是需要转换的对象或对象数组。

在这个版本中,我们使用了 map() 方法来遍历对象数组,并根据 changeName 映射关系创建了一个新的对象,避免了直接修改原始对象,确保了代码的健壮性和可读性。

回到顶部