【kk-utils】键值对双向映射工具——bidirectional-mapping

前言

kk-utils 是一款我自己基于这几年开发封装出来的前端工具库

bidirectional-mapping

bidirectional-mapping是kk-utils里的工具之一,其作用是键值对双向映射

它可以把一个字符串、数字、对象、数组按我们的映射规则进行转换

BiMap

用来生成映射规则的一个工具

BiMapConversion

用来把目标数据转换成映射规则处理后的数据

使用方法

安装

js 复制代码
npm install kk-utils-library -S
pnpm add kk-utils-library -S

编写映射规则

js 复制代码
const map = new BiMap([
  ["a", "A"], // 把'a'转成'A',也可以反过来把'A'转成'a'
  [
    "b",
    "B",
    {
      transformType: String, // 把键名对应的value进行处理,比如转成字符串,转成数字,转成Boolean
    },
  ],
  [
    "c",
    "C", // 数组嵌套数组表示c是复杂对象,里面的数据还要继续转换,c.d会变成C.D
    [
      [
        "d",
        "D",
        {
          transformSourceType: "object", // 转换数据的类型 object、map、array
          transformType: Number,
          transformInverted: true, // 是否可以反过来转换 如为true就会把原本值为'否'变成0
          transform: {
            0: "否",
            1: "是",
          },
        },
      ],
      [
        "e",
        "E",
        {
          transformType: Boolean,
        },
      ],
      [
        "f",
        "F",
        [
          [
            "g",
            "G",
            {
              transformSourceType: "map",
              transformType: Number,
              transformInverted: true,
              transform: new Map([
                [0, "zero"],
                [1, "one"],
              ]),
            },
          ],
          [
            "h",
            "H",
            {
              transformSourceType: "array",
              transformType: Number,
              transformInverted: true,
              transformLabelKey: "label",
              transformValueKey: "value",
              transform: [
                {
                  label: "否",
                  value: 0,
                },
                {
                  label: "是",
                  value: 1,
                },
              ],
            },
          ],
        ],
      ],
    ],
  ],
  [
    "children",
    "CHILDREN",
    {
      recursion: true, // 树结构 递归处理
    },
  ],
  [
    "k",
    "K",
    new BiMap([
      [0, "零"],
      [1, "一"],
    ]), // 深层对象映射可以使用数组嵌套也可以直接使用BiMap BiMap可以处理键名转换也可以处理值的转换
  ],
]);

转换数据

写一个测试数据

js 复制代码
const data = [
  {
    a: 1,
    b: 1,
    c: {
      d: 1,
      e: 1,
      f: [
        {
          g: 1,
          h: 1,
        },
      ],
    },
    children: [
      {
        a: 0,
        b: 0,
        c: {
          d: 0,
          e: 0,
          f: [
            {
              g: 0,
              h: 0,
            },
          ],
        },
        k: 0,
      },
      {
        a: 1,
        b: 1,
        c: {
          d: 1,
          e: 1,
          f: [
            {
              g: 1,
              h: 1,
            },
          ],
        },
        k: 1,
      },
    ],
    k: 1,
  },
];

使用映射规则转换数据

js 复制代码
const mapData = BiMapConversion(data, map);
console.log(mapData)

转换结果

js 复制代码
[
    {
        "A": 1,
        "B": "1",
        "C": {
            "D": "是",
            "E": true,
            "F": [
                {
                    "G": "one",
                    "H": "是"
                }
            ]
        },
        "CHILDREN": [
            {
                "A": 0,
                "B": "0",
                "C": {
                    "D": "否",
                    "E": false,
                    "F": [
                        {
                            "G": "zero",
                            "H": "否"
                        }
                    ]
                },
                "K": "零"
            },
            {
                "A": 1,
                "B": "1",
                "C": {
                    "D": "是",
                    "E": true,
                    "F": [
                        {
                            "G": "one",
                            "H": "是"
                        }
                    ]
                },
                "K": "一"
            }
        ],
        "K": "一"
    }
]

截图对比

可以看到测试数据已经按我定义好的映射规则进行了转换,无论是键名还是值,都转换成功了的

融入业务使用

比如和后端对接接口的时候,后端键名不规范,我们写逻辑的时候就要去重新命名,多处用同一接口的话,就要到处维护,不方便。再比如同一个字段的值一会是字符串,一会是数字,就会对我们的逻辑代码造成不易擦觉得影响,所以可以使用这个工具在接口处统一做出入数据管理

在接口处统一做出入数据管理

比如我要对接后端的反馈接口的CURD

定义公共分页映射

js 复制代码
// src/constants/bi-map/common/pagination/index.js
import { BiMap } from 'kk-utils-library/bidirectional-mapping';
// 分页参数
export const $paginationReqItemMap = new BiMap([
  [
    'pagination',
    'pagination',
    [
      ['page', 'pageNumber'],
      ['pageSize', 'pageSize']
    ]
  ]
]);

定义接口映射

js 复制代码
// src/constants/bi-map/feedback/index.js
import { BiMap } from 'kk-utils-library/bidirectional-mapping';
import { $paginationReqItemMap } from '../common/pagination';

// 意见反馈列表
export const $feedbackListReqItemMap = new BiMap([
  ['id', 'id'], // ID
  ['type', 'emergencyDegreeType'], // 紧急程度类型
  ['topic', 'theme'], // 主题
  ['content', 'content'] // 内容
]);
export const $feedbackListResItemMap = new BiMap([
  ['id', 'id'], // ID
  ['type', 'emergencyDegreeType'], // 紧急程度类型
  ['topic', 'theme'], // 主题
  ['content', 'content'] // 内容
]);

// 意见反馈分页
export const $feedbackPageReqItemMap = new BiMap([
  ...$feedbackListReqItemMap.sourceData, // 复用 避免多次定义
  ...$paginationReqItemMap.sourceData // 复用 避免多次定义
]);
export const $feedbackPageResItemMap = $feedbackListResItemMap; // 相同映射规则直接指向共用

// 意见反馈详情
export const $feedbackDetailReqItemMap = new BiMap([['id', 'id']]);
export const $feedbackDetailResItemMap = $feedbackListResItemMap;

// 意见反馈新建
export const $feedbackCreateReqItemMap = $feedbackListReqItemMap;
export const $feedbackCreateResItemMap = new BiMap([]);

// 意见反馈编辑
export const $feedbackUpdateReqItemMap = $feedbackListReqItemMap;
export const $feedbackUpdateResItemMap = new BiMap([]);

// 意见反馈删除
export const $feedbackDeleteReqItemMap = new BiMap([['id', 'id']]);
export const $feedbackDeleteResItemMap = new BiMap([]);

接口处使用映射做出入口参数管理

js 复制代码
// src/apis/feedback/index.js
import { BiMapConversion } from 'kk-utils-library/bidirectional-mapping';
import {
  $feedbackCreateReqItemMap,
  $feedbackCreateResItemMap,
  $feedbackDeleteReqItemMap,
  $feedbackDeleteResItemMap,
  $feedbackDetailReqItemMap,
  $feedbackDetailResItemMap,
  $feedbackListReqItemMap,
  $feedbackListResItemMap,
  $feedbackPageReqItemMap,
  $feedbackPageResItemMap,
  $feedbackUpdateReqItemMap,
  $feedbackUpdateResItemMap
} from '@/constants/bi-map/feedback';

// 分页获取意见反馈
export function getFeedbackPage(Service) {
  return (params) =>
    new Promise((resolve, reject) => {
      params = BiMapConversion(params || {}, $feedbackPageReqItemMap);
      Service.get('/api/feedbacks', params)
        .then((res) => {
          res.data = BiMapConversion(res.data || {}, $feedbackPageResItemMap);
          resolve(res);
        })
        .catch((error) => reject(error));
    });
}

// 获取意见反馈列表
export function getFeedbackList(Service) {
  return (params) =>
    new Promise((resolve, reject) => {
      params = BiMapConversion(params || {}, $feedbackListReqItemMap);
      Service.get('/api/feedbacks/list', params)
        .then((res) => {
          res.data = BiMapConversion(res.data || [], $feedbackListResItemMap);
          resolve(res);
        })
        .catch((error) => reject(error));
    });
}

// 查询意见反馈详情
export function getFeedbackDetail(Service) {
  return (params) =>
    new Promise((resolve, reject) => {
      params = BiMapConversion(params || {}, $feedbackDetailReqItemMap);
      Service.get(`/api/feedbacks/${params.id}`, { ...params, populate: '*' })
        .then((res) => {
          res.data = BiMapConversion(res.data || {}, $feedbackDetailResItemMap);
          resolve(res);
        })
        .catch((error) => reject(error));
    });
}

// 新建意见反馈
export function createFeedback(Service) {
  return (params) =>
    new Promise((resolve, reject) => {
      params = BiMapConversion(params || {}, $feedbackCreateReqItemMap);
      Service.post('/api/feedbacks', { data: params })
        .then((res) => {
          res.data = BiMapConversion(res.data || {}, $feedbackCreateResItemMap);
          resolve(res);
        })
        .catch((error) => reject(error));
    });
}

// 更新意见反馈
export function updateFeedback(Service) {
  return (params) =>
    new Promise((resolve, reject) => {
      params = BiMapConversion(params || {}, $feedbackUpdateReqItemMap);
      Service.put(`/api/feedbacks/${params.id}`, { data: params })
        .then((res) => {
          res.data = BiMapConversion(res.data || {}, $feedbackUpdateResItemMap);
          resolve(res);
        })
        .catch((error) => reject(error));
    });
}

// 删除意见反馈
export function deleteFeedback(Service) {
  return (params) =>
    new Promise((resolve, reject) => {
      params = BiMapConversion(params || {}, $feedbackDeleteReqItemMap);
      Service.delete(`/api/feedbacks/${params.id}`, params)
        .then((res) => {
          res.data = BiMapConversion(res.data || {}, $feedbackDeleteResItemMap);
          resolve(res);
        })
        .catch((error) => reject(error));
    });
}

这样只需要在接口封装处对params出参做映射转换和接收到数据时对res里的data做映射转换,我们就可以在项目里直接使用自己定义的key,出参给后台的时候也会反过来把我们的key根据映射规则转成后台原本的key再传递给后台的

其他

除了以上业务使用,我们还能用来对单个数据处理

js 复制代码
// 我们用回上面定义的new BiMap
const mapping_a = map.get('A') // a
const mapping_A = map.get('a') // A
相关推荐
只会安静敲代码的 小周5 分钟前
uniapp上传图片时(可选微信头像、相册、拍照)
前端·微信·uni-app
kovlistudio22 分钟前
红宝书第四十六讲:Node.js基础与API设计解析
前端·javascript·node.js
陈哥聊测试23 分钟前
这款自研底层框架,你说不定已经用上了
前端·后端·开源
m0_zj29 分钟前
41.[前端开发-JavaScript高级]Day06-原型关系图-ES6类的使用-ES6转ES5
开发语言·javascript·es6
蘑菇头爱平底锅39 分钟前
数字孪生-DTS-孪创城市-低空范围
前端·javascript·数据可视化
KenXu40 分钟前
Module Federation v0.12新特征详解
前端
avocado_green1 小时前
【学习笔记】从mobx迁移到redux时的概念映射
javascript
三原1 小时前
前端微应用-乾坤(qiankun)原理分析-沙箱隔离(css)
前端·架构·前端框架
琦遇1 小时前
Vue3使用AntvG6写拓扑图,可添加修改删除节点和边
前端·javascript·vue.js
Luckyfif1 小时前
🗣️面试官:有一个比较经典的 case 也想探讨一下 「页面白屏如何排查?」❤️✨
前端·面试·开源