js 数据处理

一、深拷贝

当我们需要深拷贝一些数据的时候我们通常会使用 JSON.parse(JSON.stringify()) 来进行拷贝,但是这对于一些数据来说是有弊端的,如,函数的键值取不到,当上传图片文件的时候等场景,都是不行的。那么我们可以自己自定义一个函数来进行拷贝。
直接copy可使用:(一般写在全局文件夹里再引用,如,utils/deepCopy.js)

export function deepCopy (data) {
  if (typeof data !== 'object' || data === null) {
    throw new TypeError('传入参数不是对象')
  }
  let newData = {};
  const dataKeys = Object.keys(data);
  dataKeys.forEach(value => {
    const currentDataValue = data[value];
    // 基本数据类型的值和函数直接赋值拷贝 
    if (typeof currentDataValue !== "object" || currentDataValue === null) {
      newData[value] = currentDataValue;
    } else if (Array.isArray(currentDataValue)) {
      // 实现数组的深拷贝
      newData[value] = [...currentDataValue];
    } else if (currentDataValue instanceof Set) {
      // 实现set数据的深拷贝
      newData[value] = new Set([...currentDataValue]);
    } else if (currentDataValue instanceof Map) {
      // 实现map数据的深拷贝
      newData[value] = new Map([...currentDataValue]);
    } else {
      // 普通对象则递归赋值
      newData[value] = deepCopy(currentDataValue);
    }
  });
  return newData;
}
import { deepCopy } from "@/utils/deepCopy.js";
......
deepCopy(this.childData)

二、将两个对象合并成为一个

合并对象的时候要注意是否会改变原来的数据,如果会的话,要先进行深拷贝,再合并

      let obj = {}
      let copyChildrenData = deepCopy(this.childData) //拷贝
      let copyOpenData = deepCopy(msg)  //拷贝
      obj = Object.assign(copyChildrenData, copyOpenData);  //合并

三、 对象中加入元素

例如需要把 name: ‘Jerry’ 添加到对象 obj 中:

      let obj = {}
      obj['name'] = 'Jerry'

四、 遍历对象,获取对象的键和值

tableParams = {
  name:'Jerry',
  age:'18'
}
 let obj = {}
 Object.keys(tableParams).forEach(key => {
    obj[key] = tableParams[key]
 })
 
 console.log(obj) // { name:'Jerry',age:'18' }

五、将树形数据变成一个非树形的格式(我称之为 ‘树形平铺’)

要整合下面这些数据啦:

		 tableData: [{
          id: 1,
          address: '上海市普陀区金沙江路 1518 弄',
          hasChildren:'false',
          children:[]
        }, {
          id: 2,
          address: '上海市普陀区金沙江路 1517 弄',
          hasChildren:'false',
          children:[]
        }, {
          id: 3,
          address: '上海市普陀区金沙江路 1519 弄',
          hasChildren:'true',
          children: [{
              id: 31,
              address: '上海市普陀区金沙江路 1519 弄'
            }, {
              id: 32,
              address: '上海市普陀区金沙江路 1519 弄'
          }]

不可直接copy,可参考逻辑 我也是写在一个文件里,需要的时候引用

export function readNodes (nodes = [], arr = []) {
  for (let item of nodes) {
    arr.push(item)
    //判断hasChildren的数据,有的话循环children
    if (item.hasChildren === true) readNodes(item.children, arr)
  }
  return arr
}

引用:

readNodes(this.tableData)

六、 已知某一子节点,获取所有的父级节点

export function readNodes (tree, func, path = []) {
  if (!tree) return []
  for (const data of tree) {
    // 这里按照个人的需求来存放最后返回的内容
    path.push(data.deviceId)
    if (func(data)) return path
    if (data.children) {
      const findChildren = readNodes(data.children, func, path)
      if (findChildren.length) return findChildren
    }
    path.pop()
  }
  return []
}

引入:

//我这里取的是所以父级里面的第一个,不写[0],则是获取所有啦
readNodes(this.tableData, data => data.deviceId === msg.deviceId)[0]

七、 将拿到的数据和相对应的数据相匹配(一)

在js中直接处理:后端传回0,1数值,前端根据0为女生,1为男生

data(){
	return:{
		lala:[
			{"sex":0},
			{"sex":1},
			{"sex":1}
		]
	}
}
methods:{
	let sexObj = {
		"0":"女生""1":"男生"
	}
	this.lala.foreach(elem =>{
		let datas = {
		 aaa : sexObj[elem.sex]  //这里匹配
		 } 
	})
}

八、 将拿到的数据和相对应的数据相匹配(二)

在html中进行匹配:
在静态资源文件夹中新建一个js文件:
filters.js

//电量等级与百分比参照表
export const lvMapTest = {
  '<3.8v': '1%',
  '3.8v~3.9v': '5%',
  '3.9v~4.0v': '10%',
  '4.0v~4.1v': '15%',
  '4.1v~4.2v': '20%',
  '4.2v~4.3v': '25%',
  '4.3v~4.4v': '30%',
  '4.4v~4.5v': '35%',
  '4.5v~4.6v': '40%',
  '4.6v-4.7v': '45%',
  '4.7v~4.8v': '50%',
  '4.8v~5.1v': '60%',
  '5.1v~5.4V': '70%',
  '5.4v~5.7v': '80%',
  '5.7v~6v': '90%',
  '>6v': '100%',
  'undefine': '设备返回电量异常'
}

//电量等级过滤器
export const lvMapFilterTest = (lv) => {
  return lvMapTest[lv]
}

在需要使用到的.vue中:

<template>
	<span>{{ item.state | lvMapFilterTest }}</span>
<template>
<script>
  import { lvMapFilter, lvMapFilterTest } from "@/utils/domainFilter";
  export default {
  //这里千万别漏啦
	 filters: {
        lvMapFilterTest
     }
  }
<script>

九、 将拿到的数据分别组合成对象的 键和键值

listData:[{
	functionTag:"tag1",
	functionName:"name1",
	},{
	functionTag:"tag2",
	functionName:"name2",
	},{
	functionTag:"tag3",
	functionName:"name3",
	}
]
// 需要拼接成 tag1_0: name1
let obj = {}
listData.forEach(element => {
	obj[element.functionTag] = element.functionName
})

打印结果:

  {
	tag1:name1,
	tag2:name2,
	tag3:name3
  }

十、 将拿到的数据分别组合成对象的 键和键值(需拼接),如 function_1:tag

listData:[{
	functionTag:"tag1",
	strValue:"1",
	functionName:"name1",
	},{
	functionTag:"tag2",
	strValue:"2",
	functionName:"name2",
	},{
	functionTag:"tag3",
	strValue:"3",
	functionName:"name3",
	}
]
// 需要拼接成 tag1_1: name1
let obj = {}
listData.forEach(element => {
	obj [`${element.functionTag}_${element.strValue}`] = element.functionName
})

打印结果

 {
	tag1_1: name1,
	tag2_2: name2,
	tag3_3: name3
 }

十一、 检测数据里面是否有某字符串

//检测是否有 dataInfo.dataType.specs
dataInfo.dataType.hasOwnProperty("specs")

十二、 过滤出两个数组里的不同数据

let remarks = [0, 1, 2, 5]
let replaceStrVal = [2, 5, 8, 9]
let remarksTag = remarks.filter(item => !replaceStrVal.some(elem => elem === item))

打印结果:
[0, 1, 8, 9]

十三、过滤出两个数组中相同的项

   let test1 = [{
      name: '轮播',
      num: '123'
    },

    {
      name: '广告',
      num: '123'
    }]
    
    let test2 = [{
      name: '轮播',
      num: '123'
    },
    {
      name: '广告',
      num: '123'
    },
    {
      name: '可以',
      num: '123'
    }]
    //啦啦啦,这里实现逻辑
    let result = test1.filter((t1) => {
      return test2.find((t2) => t2.name === t1.name)
    })
    console.log(result, 'resultresult'); 

打印:
在这里插入图片描述

十四、 数组转字符并用逗号分隔

let obj = String(element.productNames.join(','))

十五、相关字符串作为操作依据 indexOf

String.prototype.indexOf() :搜索指定的值,如果没有找到,则返回 -1。也就相当于是模糊查询。
使用方法:

         if (res.message.indexOf('账号已在其它地方登录') !== -1 || res.message.indexOf("token无效") !== -1) {
                removeAccessToken()
                removeRefreshToken()
            }

十六、(?.)和(??),对可选链和返回值的操作

dataMsg.list = data?.data.items ?? []

可选链操作符( ?. )允许读取位于连接对象链深处的属性的值,而不必明确验证链中的每个引用是否有效。引用为空(nullish ) (null 或者 undefined) 的情况下不会引起错误,该表达式短路返回值是 undefined。 文档

const adventurer = {
  name: 'Alice',
  cat: {
    name: 'Dinah'
  }
};

const dogName = adventurer.dog?.name;
console.log(dogName);
// expected output: undefined

空值合并操作符(??)是一个逻辑操作符,当左侧的操作数为 null 或者 undefined 时,返回其右侧操作数,否则返回左侧操作数。文档

console.log(1 ?? "a")			//1
console.log(0 ?? "a") 			//0
console.log(null ?? "a") 		//a
console.log(undefined ?? "a")  //a
console.log(-1 ?? "a") 		//-1
console.log("" ?? "a") 		//''

十七、将数组中的某个对象的数组平铺开

需求:

let content1 = [
	{id:'1', includeArr:[{id:1},{id:2}]},
	{id:'3', includeArr:[{id:3}]}
]

变成:
let  content2 = [
	{id:'1', includeArr:[{id:1}]},
	{id:'1', includeArr:[{id:2}]},
	{id:'3', includeArr:[{id:3}]},
]

方案一(笨方法):

let arr = []
let content1 = [
	{id:'1', includeArr:[{id:1},{id:2}]},
	{id:'3', includeArr:[{id:3}]}
]
content1.forEach((x)=>{
	x.arr.forEach((y)=>{
		arr.push({...x,arr:[y]})	
	})
})

方案二:

content1.flatMap(item => item.includeArr.map(o => ({id: item.id, includeArr: o})))

多维数组拉成一维
灵活处理数组

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值