对象和数组神奇之处转换
在平常开发中,需要数组和对象直接转换,方便我们找对应属性的数据
数组 => 对象
- 场景一 : 当后台返回一个数据字典的数据,我们要根据数据字典的value,显示对应的label
let arr = [
{
id: "001",
dictLabel: "男",
dictValue: 1
},
{
id: "002",
dictLabel: "女",
dictValue: 2
},
{
id: "003",
dictLabel: "未知",
dictValue: 0
}
]
let sexOptions = arr.reduce((pre,cur) => {
pre[cur.dictValue] = cur.dictLabel
return pre;
}, {})
console.log(sexOptions)
//{0: "未知", 1: "男", 2: "女"}
- 场景二: 当后台返回一个 线性结构的数据, 但是我们前端树形组件需要树形结构的数据,去显示树形组件。
- 正常使用
let arr = [
{
id:1,
name:"zs"
},
{
id:2,
name: "ls"
}
]
//通过数组 每一个元素的id,生成一个对象
//第一种方式
// let obj = {}
// arr.forEach(item => {
// if(! obj[item.id]) {
// obj[item.id] = item;
// }
// })
//第二种方式 推荐
let obj = {}// 必须通过arr动态生成 对象, 否在 生成的对象变化,不会影响arr里面对象
obj = arr.reduce((pre,cur) => {
if(! pre[cur.id]) {
pre[cur.id] = cur;
return pre;
}
}, obj)
arr.forEach(item => {
obj[item.id].children ? obj[item.id].children.push(1) : obj[item.id].children = []
})
console.log(obj,arr)
注意:这里obj必须通过arr动态生成 对象, 否在 生成的对象变化,不会影响arr里面对象(引用类型);这样才能让我们数组里面的对象都会进行改变
结果显示:
P0T9F`G}2$RM6U}(NYLW68K.png
- 非正常使用
let arr = [
{
id:1,
name:"zs"
},
{
id:2,
name: "ls"
}
]
//不通过arr生成obj
//这是我们自定义的对象
let obj = {
1: {
id: 1,
name: "zs"
},
2: {
id: 2,
name: "ls"
}
}
arr.forEach(item => {
obj[item.id].children ? obj[item.id].children.push(1) : obj[item.id].children = []
})
console.log(obj,arr)
结果显示:
I[{)J@KBPO7`$LGERUPT]_J.png
注意: 从结果显示我们,我们的自定义的对象 变化,但是对应的数组里的对象,没有变化的; 导致我们想改变数组的数据结构实现不了
- 线性结构 => 树形结构(业务场景:菜单,实体类分类(部门,药品,..等),)
let array = [
{
id: 1,
parent_id: 0,
name: "四川省"
},
{
id: 2,
parent_id: 0,
name: "广东省"
},
{
id: 3,
parent_id: 0,
name: "江西省"
},
{
id: 5,
parent_id: 1,
name: "成都市"
},
{
id: 6,
parent_id: 5,
name: "锦江区"
},
{
id: 7,
parent_id: 6,
name: "九眼桥"
},
{
id: 8,
parent_id: 6,
name: "兰桂坊"
},
{
id: 9,
parent_id: 2,
name: "东莞市"
},
{
id: 10,
parent_id: 9,
name: "长安镇"
},
{
id: 11,
parent_id: 3,
name: "南昌市"
}
]
function listToTree(list) {
let map = {};
//
list.forEach(item => {
if (! map[item.id]) {
map[item.id] = item;
}
});
console.log(map)
console.log(list)
list.forEach(item => {
if (item.parent_id !== 0) {
map[item.parent_id].children ? map[item.parent_id].children.push(item) : map[item.parent_id].children = [item];
}
});
console.log(list)
return list.filter(item => {
if (item.parent_id === 0) {
return item;
}
})
}
console.log(listToTree(array));
- 进一步的封装完善
//list: 后台返回的数据 ; options: 需要初始化的属性参数
function listToTree(list, otpions) {
// 属性初始化
// name: 表示原数据的从后台返回的字段名称,name2:表示前端组件需要的字段名称
let {id = "id", parentId = "parentId", name = "name", name2 = "label" } = options;
let map = {}
map = arr.reduce((pre,cur) => {
if(! pre[cur.id]) {
//初始化自定义显示属性(因为有些组件需要传入的字段 label...等)
pre[name2] = cur.name;
pre[cur.id] = cur;
return pre;
}
}, map)
list.forEach(item => {
if (item.parentId !== 0) {
map[item.parentId].children ? map[item.parentId].children.push(item) : map[item.parentId].children = [item];
}
});
return list.filter(item => {
if (item.parentId === 0) {
return item;
}
})
}
-
真实业务场景使用 vue-treeselect,element-ui;效果图如下
GGVZ5D910NOGJXA70~RG`ZC.png
YHOM6WO27Z0LTL8JUOX49SX.png
核心sql
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.AppMedicineMapper">
<!--resultMap 目的就是查询后的数据 进行赋值映射,如果没有就是null-->
<resultMap type="com.ruoyi.system.domain.AppMedicine" id="AppMedicineResult">
<result property="id" column="id"/>
<result property="medicineId" column="medicine_id"/>
<result property="name" column="name"/>
<result property="type" column="type"/>
<result property="picture" column="picture"/>
<result property="attention" column="attention"/>
<result property="disable" column="disable"/>
<result property="des" column="des"/>
<result property="function" column="function"/>
<result property="diseaseId" column="disease_id"/>
<result property="medicinetypeId" column="medicinetype_id"/>
<result property="delFlag" column="del_flag"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
<association property="appMedicineType" column="medicinetype_id" javaType="AppMedicineType" resultMap="medicineType" />
</resultMap>
<resultMap id="medicineType" type="AppMedicineType">
<!--必须把关联的字段 不能和主表字段区别-->
<id property="id" column="type_id"></id>
<result property="name" column="type_name"></result>
</resultMap>
<!--查询药品,关联药品分类,-->
<select id="selectMedicineList" parameterType="AppMedicine" resultMap="AppMedicineResult">
select t1.id,t1.medicine_id,t1.name, t1.picture, t1.attention,t1.`disable`,t1.des,t1.`function`,t1.disease_id,t1.medicinetype_id,
t1.del_flag,t1.create_by,t1.create_time,t1.update_by,t1.update_time,
t2.id as type_id, t2.name as type_name
from app_medicine t1
left join app_medicine_type t2 on t1.medicinetype_id = t2.id
where t1.del_flag = "0"
<if test="name != null and name != ''">
and t1.name like concat("%", #{name}, "%")
</if>
</select>
</mapper>
核心template
<el-table v-loading="loading" :data="AppMedicineList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="药品id" align="center" prop="id" v-if="false"/>
<el-table-column label="药品名称" align="center" prop="name" />
<el-table-column label="分类名称" align="center" prop="appMedicineType.name" />
<el-table-column label="药品图片" align="center" prop="picture" class-name="myImg" >
<template slot-scope="scope">
<img :src="scope.row.picture" alt="" style="width:40px;height:40px" />
</template>
</el-table-column>
<el-table-column show-overflow-tooltip label="注意事项" align="center" prop="attention" />
<el-table-column show-overflow-tooltip label="药品忌" align="center" prop="disable" />
<el-table-column show-overflow-tooltip label="药品描述" align="center" prop="des" />
<el-table-column show-overflow-tooltip label="药品功效" align="center" prop="function" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['system:AppMedicine:edit']"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['system:AppMedicine:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
对象 => 数组
- 常用的操作
let obj = {
id: "001",
name: "zs",
age: 10
}
Object.keys(obj).forEach(item => {
console.log(item)
})
- 我们为什么要 对象转换成数组? 方便业务场景需要,因为不管遍历,还是渲染,数组方便对数据
变形(分组,排序,合并,交叉,非交叉,统计)
敬请期待