js如何改变对象里的键

<template>
    <Cascader :data="data" v-model="value1"></Cascader>
</template>
<script>
    export default {
        data () {
            return {
                value1: [],
                data: [{
                    value: 'beijing',
                    label: '北京',
                    children: [
                        {
                            value: 'gugong',
                            label: '故宫'
                        },
                        {
                            value: 'tiantan',
                            label: '天坛'
                        },
                        {
                            value: 'wangfujing',
                            label: '王府井'
                        }
                    ]
                }, {
                    value: 'jiangsu',
                    label: '江苏',
                    children: [
                        {
                            value: 'nanjing',
                            label: '南京',
                            children: [
                                {
                                    value: 'fuzimiao',
                                    label: '夫子庙',
                                }
                            ]
                        },
                        {
                            value: 'suzhou',
                            label: '苏州',
                            children: [
                                {
                                    value: 'zhuozhengyuan',
                                    label: '拙政园',
                                },
                                {
                                    value: 'shizilin',
                                    label: '狮子林',
                                }
                            ]
                        }
                    ],
                }]
            }
        }
    }
</script>

如何把这个value和label换成gcId和gcName 改变这个键值

阅读 3.4k
5 个回答
function map(list, cb) {
  return list.map(item => {
      const res = cb(item);
    if(item.children) res.children = map(item.children, cb);
    return res;
  })
}


var data = [
  {
    value: 'beijing',
    label: '北京',
    children: [
      {
        value: 'gugong',
        label: '故宫'
      },
      {
        value: 'tiantan',
        label: '天坛'
      },
      {
        value: 'wangfujing',
        label: '王府井'
      }
    ]
  }
];
map(data, item => ({
    gcId: item.value,
    gcName: item.label,            
}));
JSON.parse(JSON.stringify({label: 'asdfasdf'}).replace(/"label":/g, '"gcName":'))

把对象转换成字符串, 进行替换, 再parse成对象
防止替换出错多匹配一个key后面的冒号, 加双引号是因为转为字符串之后会带上双引号

测试对象

let dataArray = [{
    value: 'beijing',
    label: '北京',
    children: [
        {
            value: 'gugong',
            label: '故宫'
 },
        {
            value: 'tiantan',
            label: '天坛'
 },
        {
            value: 'wangfujing',
            label: '王府井'
 }
    ]
}, {
    value: 'jiangsu',
    label: '江苏',
    children: [
        {
            value: 'nanjing',
            label: '南京',
            children: [
                {
                    value: 'fuzimiao',
                    label: '夫子庙',
                }
            ]
        },
        {
            value: 'suzhou',
            label: '苏州',
            children: [
                {
                    value: 'zhuozhengyuan',
                    label: '拙政园',
                },
                {
                    value: 'shizilin',
                    label: '狮子林',
                }
            ]
        }
    ],
}];

实现代码

// 程序入口
replace(dataArray)


function replace(obj) {
    // 如果是数组 则不断遍历
 if (Array.isArray(obj)) {
     obj.forEach(d => replace(d))
     return
    }
    
    
 // 如果是对象,则获取其值临时保存
 let tValue = obj['value'];
 let tLabel = obj['label'];
 
 
 // 删除新值,重新创建gcID & gcName 并赋值
 delete obj['value'];
 delete obj['label'];
 obj.gcId = tValue;
 obj.gcName = tLabel;
 
 // 如果有children则递归执行
 if (obj.children) {
        replace(obj.children)
    }
}

结果

image.png

function mapData(model) {

// 判断如果是数组,就对单个元素使用 mapData 进行映射处理
if (Array.isArray(model)) {
    return model.map(it => mapData(it));
}

const r = { ...model }
["label", "value"].forEach(name => delete r[name]);

const { label, value } = model;
const r = { gcId: value, gcName: label };

// 如果有 children,对 children 数组进行映射处理
if (model.children) {
    r.children = mapData(model.children);
}

return r;

}
就是一个简单的递归映射就好了(看注释,不懂就评论中继续问):

function mapData(model) {
    // 判断如果是数组,就对单个元素使用 mapData 进行映射处理
    if (Array.isArray(model)) {
        return model.map(it => mapData(it));
    }

    const { label, value } = model;
    const r = { gcId: value, gcName: label };

    // 如果有 children,对 children 数组进行映射处理
    if (model.children) {
        r.children = mapData(model.children);
    }

    return r;
}

上面处理了每个元素只有 labelvaluechildren 属性的情况,如果还有其他属性,可以过滤,比如先复制,再删除

    const r = { ...model }
    ["label", "value"].forEach(name => delete r[name]);

或者通过 Lodash 的 omit() 来处理

    // 记得 import _ from "lodash";

    const r = _.omit(model, ["label", "value", "children"]);
    ({ label: r.gcId, value: r.gcName } = model);

    // 如果有 children,对 children 数组进行映射处理
    if (model.children) {
        r.children = mapData(model.children);
    }

对象中的键名是不可变的,你只能重新生成或者说构造一个按新键名生成的对象。
其实一个办法是该对象绑定一个特殊的查询方法,在查询方法中gcId和gcName分别对应原对象的value和label

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题