js 数据常用操作备忘录 持续更新中

204 阅读5分钟

不要吹灭你的灵感和你的想象力; 不要成为你的模型的奴隶。 ——文森特・梵高

懒人图祭天

image.png

数组操作

1、对象数组根据某个值进行去重

通过定义一个存在的集合去判断集合中是否存在

let data = [{id:1},{id:2},{id:3},{id:1}];
var obj = {};
data = data.reduce(function (item, next) {
//需要去重项 例如:id + 编码 + 名称
  name = next.id + next.code + next.name
  obj[name] ? '' : (obj[name] = true && item.push(next))
  return item
}, [])

2、获取数组中某个值的集合

// 获取到数组中某个值的合集
 let canSumFlag = new Set(profuctNumConfig.map(item => item = item.canSumFlag))
 // 获取到去重后的数组
  let arr = Array.from(canSumFlag)
  //去重的简单写法
  const arr = [1, 1, 2, 2, 3, 4, 5, 5] const newArr = [...new Set(arr)]

3、判断数组的几种方式

通过instanceof判断

instanceof运算符用于检验构造函数的prototype属性是否出现在对象的原型链中的任何位置,返回一个布尔值

let a = []
a instanceof Array; // true
let b = {}
b instanceof Array; // false
 //instanceof 运算符检测Array.prototype属性是否存在于变量a的原型链上
 //显然a是一个数组,拥有Aarray.prototype属性,所以为true 

通过constructor判断

实例的构造函数属性constructor指向构造函数,通过constructor属性可以判断是否为一个数组

let a = [7,8,9];
a.constructor === Array; // true

通过Object.prototype.toString.call()判断

Object.prototype.toString.call()可以获取到对象的不同类型

let a = [7,8,9];
Object.prototype.toString.call(a) === '[Object Array]'; // true

通过Array.isArray()判断

Array.isArray()用于确定传递的值是否是一个数组,返回一个布尔值

let a = [7,8,9];
Array.isArray(a); // true

有个问题是Array.isArray()是ES5新增的方法,目的就是提供一个稳定可用的数组判断方法,对于ES5之前不支持此方法的问题,我们其实可以做好兼容进行自行封装,如下:

if(!Array.isArray){
Array.isArray=function(argument){
return Object.prototype.toString.call(argument)=== '[object Array]';

补充:typeof

typeof 只能检测 基本数据类型,包括boolean、undefined、string、number、symbol,而null ,Array、Object ,使用typeof出来都是Object,函数的typeof 是function 无法检测具体是哪种引用类型。

image.png

4、取出两个数组中的不同或相同元素

取出两个数组的不同元素

var arr1 = [0,1,2,3,4,5]; 
 var   arr2 = [0,4,6,1,3,9]; 
 function getArrDifference(arr1, arr2) { 
   return arr1.concat(arr2).filter(  function  (v, i, arr) { 
     return arr.indexOf(v) === arr.lastIndexOf(v); 
   }); 
 } 
 console.log(getArrDifference(arr1,arr2)); 
//输出:(4) [2, 5, 6, 9]`

取出两个数组的相同元素

var arr1 = [0,1,2,3,4,5];
var arr2 = [0,4,6,1,3,9];
function getArrEqual(arr1, arr2) {
    let newArr = [];
    for (let i = 0; i < arr2.length; i++) {
      for (let j = 0; j < arr1.length; j++) {
        if(arr1[j] === arr2[i]){
          newArr.push(arr1[j]);
        }
    }
   }
   return newArr;
}
console.log(getArrEqual(arr1, arr2));
 //输出:(4) [0, 4, 1, 3]

5、数组中是否存在某个值

values.every(value => isNaN(value))

6、生成类似[1-100]这样的的数组:

测试大量数据的数组时可以这样生成:

// fill
const arr = new Array(100).fill(0).map((item, index) => index + 1)

// Array.from() 评论区大佬指出
const arr = Array.from(Array(100), (v, k) => k + 1)

// ... + array.keys() 评论区大佬指出 生成的是0-99的数组
const ary = [...Array(100).keys()] 

new Array(100) 会生成一个有100空位的数组,这个数组是不能被map(),forEach(), filter(), reduce(), every() ,some()遍历的,因为空位会被跳过(for of不会跳过空位,可以遍历)。 [...new Array(4)] 可以给空位设置默认值undefined,从而使数组可以被以上方法遍历。

7、 数组取交集

const a = [0, 1, 2, 3, 4, 5]
const b = [3, 4, 5, 6, 7, 8]
const duplicatedValues = [...new Set(a)].filter(item => b.includes(item))
duplicatedValues // [3, 4, 5]

8、数组取差集

const a = [0, 1, 2, 3, 4, 5]
const b = [3, 4, 5, 6, 7, 8]
const diffValues = [...new Set([...a, ...b])].filter(item => !b.includes(item) || !a.includes(item)) // [0, 1, 2, 6, 7, 8]

9、 数组转对象

const arr = [1, 2, 3, 4]
const newObj = {...arr} // {0: 1, 1: 2, 2: 3, 3: 4}
const obj = {0: 0, 1: 1, 2: 2, length: 3}
// 对象转数组不能用展开操作符,因为展开操作符必须用在可迭代对象上
let newArr = [...obj] // Uncaught TypeError: object is not iterable...
// 可以使用Array.form()将类数组对象转为数组
let newArr = Array.from(obj) // [0, 1, 2]

10、 数组摊平

const obj = {a: '群主', b: '男群友', c: '女裙友', d: '未知性别'}
const getName = function (item) { return item.includes('群')}
// 方法1
const flatArr = Object.values(obj).flat().filter(item => getName(item))
// 经大佬指点,更加简化(发现自己的抽象能力真的差~)
const flatArr = Object.values(obj).flat().filter(getName)

二维数组用array.flat(),三维及以上用array.flatMap()array.flat(2)可以传参数字如 2,表示要摊平的层数。

11、数组排序

  newV.sort((a, b) => {
         return a.num>b.num ? 1  : -1
       })

Promise操作

new Promise

  new Promise((resolve, reject)=>{
     ...
  });

Promise.all

 // Promise.all() 方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。
const p = Promise.all([p1, p2, p3]);
// 生成一个Promise对象的数组
const promises = [1, 3, 5, 7, 9].map( ()=> {
    return  new Promise((resolve, reject)=>{
     ...
  });
});
Promise.all(promises).then(data=> {
    console.log("ok")
    console.log('Contents: ', JSON.stringify(data));
}).catch(function(reason){
   console.log('出错了',reason)
});

时间常用操作

时间戳转化时间

function timestampToTime(timestamp) {
        var date = new Date(timestamp * 1000);//时间戳为10位需*1000,时间戳为13位的话不需乘1000
        var Y = date.getFullYear() + '-';
        var M = (date.getMonth()+1 < 10 ? '0'+(date.getMonth()+1):date.getMonth()+1) + '-';
        var D = (date.getDate()< 10 ? '0'+date.getDate():date.getDate())+ ' ';
        var h = (date.getHours() < 10 ? '0'+date.getHours():date.getHours())+ ':';
        var m = (date.getMinutes() < 10 ? '0'+date.getMinutes():date.getMinutes()) + ':';
        var s = date.getSeconds() < 10 ? '0'+date.getSeconds():date.getSeconds();
        return Y+M+D+h+m+s;
    }
 timestampToTime(1403058804);
 console.log(timestampToTime(1403058804));//2020-06-18 10:33:24
// 获取当年年月日时分秒

/**
 * 格式化時間戳
 * @param date {Number, String} 转换的時間戳
 * @param format {Number} 轉換格式
 * @param  dayNum {Number} 增减天数
 * @return {String}
 */
export function dateFormat(date, format, dayNum = 0) {
  if (!format) format = 'yyyy/MM/dd'

  if (!date) {
    return ''
  }

  const addZero = (number) => {
    if (number < 10) return '0' + number
    else return '' + number
  }
  date = date * 1 + dayNum * 24 * 60 * 60 * 1000

  if (!(date instanceof Date)) {
    date = new Date(parseInt(date))
  }
  if (format.indexOf('yyyy') >= 0) {
    format = format.replace(/yyyy/g, date.getFullYear())
  } else if (format.indexOf('yy') >= 0) {
    format = format.replace(/yy/g, (date.getFullYear() + '').substr(2, 2))
  }
  if (format.indexOf('MM') >= 0) {
    format = format.replace(/MM/g, addZero(date.getMonth() + 1))
  } else if (format.indexOf('M') >= 0) {
    format = format.replace(/M/g, date.getMonth() + 1)
  }
  if (format.indexOf('dd') >= 0) {
    format = format.replace(/dd/g, addZero(date.getDate()))
  } else if (format.indexOf('d') >= 0) {
    format = format.replace(/d/g, date.getDate())
  }
  if (format.indexOf('HH') >= 0) {
    format = format.replace(/HH/g, addZero(date.getHours()))
  } else if (format.indexOf('H') >= 0) {
    format = format.replace(/H/g, date.getHours())
  }
  if (format.indexOf('mm') >= 0) {
    format = format.replace(/mm/g, addZero(date.getMinutes()))
  } else if (format.indexOf('m') >= 0) {
    format = format.replace(/m/g, date.getMinutes())
  }
  if (format.indexOf('ss') >= 0) {
    format = format.replace(/ss/g, addZero(date.getSeconds()))
  } else if (format.indexOf('s') >= 0) {
    format = format.replace(/s/g, date.getSeconds())
  }
  return format
}

js中获取不同时间的方式


// 获取当前时间戳(以s为单位)
var timestamp = Date.parse(new Date());
timestamp = timestamp / 1000;
//当前时间戳为:1403149534
console.log("当前时间戳为:" + timestamp);
 
// 获取某个时间格式的时间戳
var stringTime = "2014-07-10 10:21:12";
var timestamp2 = Date.parse(new Date(stringTime));
timestamp2 = timestamp2 / 1000;
//2014-07-10 10:21:12的时间戳为:1404958872 
console.log(stringTime + "的时间戳为:" + timestamp2);
 
// 将当前时间换成时间格式字符串
var timestamp3 = 1403058804;
var newDate = new Date();
newDate.setTime(timestamp3 * 1000);
// Wed Jun 18 2014 
console.log(newDate.toDateString());
// Wed, 18 Jun 2014 02:33:24 GMT 
console.log(newDate.toGMTString());
// 2014-06-18T02:33:24.000Z
console.log(newDate.toISOString());
// 2014-06-18T02:33:24.000Z 
console.log(newDate.toJSON());
// 2014年6月18日 
console.log(newDate.toLocaleDateString());
// 2014年6月18日 上午10:33:24 
console.log(newDate.toLocaleString());
// 上午10:33:24 
console.log(newDate.toLocaleTimeString());
// Wed Jun 18 2014 10:33:24 GMT+0800 (中国标准时间)
console.log(newDate.toString());
// 10:33:24 GMT+0800 (中国标准时间) 
console.log(newDate.toTimeString());
// Wed, 18 Jun 2014 02:33:24 GMT
console.log(newDate.toUTCString());

正则

输入框正则,只能输入数字和小数

/*只能输入串纯数字,小数点不可以*/
<input type="text" οnkeyup="value=value.replace(/[^\d]/g,'')"/*保留两位小数*/ 
<input type="text" οnkeyup="value=value.replace(/^\D*(\d*(?:\.\d{0,2})?).*$/g, '$1')" >   
/*保留一位小数*/ 
<input type="text" οnkeyup="value=value.replace(/^\D*(\d*(?:\.\d{0,1})?).*$/g, '$1')" >   
/*第一位不为0,且不能输入小数* / 
<input type="text" οnkeyup="value=value.replace(/[^\d]/g,'').replace(/^0{1,}/g,'')" >