Json 常用方法
json 深拷贝
/*方式一:Object.assign()
* 1、对象只有一级属性时,可以深拷贝
* 2、对象中有多级属性时,二级属性后就是浅拷贝
*/
var oldObj = {name: "张三", age: 25, info: {num: "001"}};
var newObj = Object.assign({},oldObj);
newObj.name = "李四";
newObj.info.num = "002";
console.log("oldObj:" + JSON.stringify(oldObj)); // oldObj:{"name":"张三","age":25,"info":{"num":"002"}}
console.log("newObj:" + JSON.stringify(newObj)); // newObj:{"name":"李四","age":25,"info":{"num":"002"}}
/*方式二:JSON对象
* 无法实现对象中方法的深拷贝,JSON.stringify()会自动过滤对象中的方法
*/
var oldObj = {name: "张三", age: 25, info: {num: "001"}, xxx: function(){}};
var newObj = JSON.parse(JSON.stringify(oldObj));
newObj.name = "李四";
newObj.info.num = "002";
console.dir(oldObj); // {"name":"张三","age":25,"info":{"num":"001"}, xxx: function(){}}
console.dir(newObj); // {"name":"李四","age":25,"info":{"num":"002"}}
/*方式三:递归
* 实现对象中方法的深拷贝
*/
var oldObj = {name: "张三", age: 25, info: {num: "001"}, xxx: function(){}};
function deepClone(obj){
let objClone = Array.isArray(obj) ? [] : {};
if (obj && typeof obj === 'object') {
for(let key in obj){
if (obj[key] && typeof obj[key] === 'object'){
objClone[key] = deepClone(obj[key]);
}else{
objClone[key] = obj[key]
}
}
}
return objClone;
}
newObj = deepClone(oldObj);
console.dir(oldObj); // {"name":"张三","age":25,"info":{"num":"001"}, xxx: function(){}}
console.dir(newObj); // {"name":"张三","age":25,"info":{"num":"001"}, xxx: function(){}}
json --> 数组
let jsonObj = {'未完成':5, '已完成':8, '待确认':4, '已取消':6};
let arr = []
for (let i in jsonObj) {
let item = {};
item[i] = jsonObj[i];
arr.push(item);
}
console.log(arr); // [{未完成: 5},{已完成: 8},{待确认: 4},{已取消: 6}]
获取json对象长度
let jsonlen=0;
for(let key in brokers){
jsonlen ++;
}
数组常用方法
一、改变原始数组的方法(7个)
let a = [1,2,3,4];
【ES5】a.splice()
a.unshift()/ a.push()
a.shift() / a.pop()
a.sort() / a.reverse()
splice() 添加/删除数组元素
语法:a.splice(index,howmany,item1,…,itemX)
参数:
index: 必需。整数,规定添加/删除项目的位置,使用负数可从数组结尾处规定位置。
howmany:必需。要删除的项目数量。如果设置为 0,则不会删除项目。
item1,…,itemX:可选。向数组添加的新项目。
返回值:没有删除元素,返回空数组;删除元素,返回含有被删除元素的数组。
example_1: 添加元素
var a = [1, 2, 3, 4];
var b = a.splice(0,0,0);
console.log(b); // [] 没有删除元素,返回空数组
console.log(a); // [0, 1, 2, 3, 4]
a.splice(-1,0,5);
console.log(a); // [0, 1, 2, 3, 5, 4]
example_2: 删除元素
var a = [1,2,3,4];
var b = a.splice(1,1);
console.log(a); // [1, 3, 4]
console.log(b); // [2] 删除元素,返回含有被删除元素的数组
example_3: 删除并添加元素
var a = [1,2,3,4];
var b = a.splice(1,1,'添加1','添加2');
console.log(a); // [1, "添加1", "添加2", 3, 4]
console.log(b); // [2] 删除元素,返回含有被删除元素的数组
unshift() 向数组的开头添加一个或更多元素
语法:a.unshift(ele1,ele2,…,eleX)
参数:
ele1:必需。向数组添加的第一个元素。
ele2:可选。向数组添加的第二个元素。
eleX:可选。可添加若干个元素
返回值:返回新数组的长度。
example_1:添加少量元素
var a = [1,2,3,4];
var b = a.unshift('开头1','开头2');
console.log(a); // ["开头1", "开头2",1, 2, 3, 4]
console.log(b); // 6
example_2: 添加多个元素
var a = [1,2,3,4];
var c = ['开头1','开头2','开头3'];
var b = a.unshift(...c);
console.log(a); // ['开头1','开头2','开头3',1, 2, 3, 4]
console.log(b); // 7
push() 向数组的末尾添加一个或多个元素
语法:a.push(ele1,ele2,…,eleX)
参数:
ele1:必需。向数组添加的第一个元素。
ele2:可选。向数组添加的第二个元素。
eleX:可选。可添加若干个元素
返回值:返回新数组的长度。
example_1:添加少量元素
var a = [1,2,3,4];
var b = a.push('末尾1','末尾2');
console.log(a); // [1, 2, 3, 4, "末尾1", "末尾2"]
console.log(b); // 6
example_2: 添加多个元素
var a = [1,2,3,4];
var c = ['末尾1','末尾2','末尾3'];
var b = a.push(...c);
console.log(a); // [1, 2, 3, 4, "末尾1", "末尾2", "末尾3"]
console.log(b); // 7
shift() 删除数组的第一个元素
语法:a.shift()
返回值:数组原来的第一个元素的值。
example:
var a = [1,2,3,4];
var b = a.shift();
console.log(a); // [2, 3, 4]
console.log(b); // 1
pop() 删除数组的最后一个元素
语法:a.pop()
返回值:数组原来的最后一个元素。
example:
var a = [1,2,3,4];
var b = a.pop();
console.log(a); // [1, 2, 3]
console.log(b); // 4
sort() 数组排序
语法:a.sort(sortby)
参数:
sortby:可选。规定排序顺序的比较函数函数。
sortby:省略,默认按字母升序,如果元素不是字符串的话,会调用toString()方法将元素转化为字符串的Unicode,然后再比较
sortby(a,b) < 0, a在b之前
sortby(a,b) = 0, a,b位置不变
sortby(a,b) > 0, a在b之后
返回值:排序后的原数组。
example_1:比较数字
var number = [21,37,45,-12,0,37];
number.sort((a,b) => a - b); //升序排列
console.log(number); // [-12, 0, 21, 37, 37, 45]
number.sort((a,b) => b - a); //降序排列
console.log(number); // [45, 37, 37, 21, 0, -12]
example_2:比较对象
var items = [
{ name: 'Edward', value: 21 },
{ name: 'Sharpe', value: 37 },
{ name: 'And', value: 45 },
{ name: 'The', value: -12 },
{ name: 'Magnetic',value: 0 },
{ name: 'Zeros', value: 37 }
];
items.sort( (a, b) => a.value - b.value);
console.log(items); //[{name: "The", value: -12},{name: "Magnetic", value: 0},{name: "Edward", value: 21},{name: "Sharpe", value: 37},{name: "Zeros", value: 37},{name: "And", value: 45}]
example_3:多字段比较
var items = [
{ class:'一班', name: 'Edward', value: 37 },
{ class:'二班', name: 'Sharpe', value: 37 },
{ class:'一班', name: 'And', value: 45 },
{ class:'二班', name: 'The', value: -12 },
{ class:'一班', name: 'Magnetic',value: 37 },
{ class:'二班', name: 'Zeros', value: 37 }
];
items.sort((a, b) => {
if(a.value == b.value) {
// 中文不能直接用相减的形式
return a.class > b.class ? 1 : -1;
} else {
return a.value - b.value;
}
});
console.log(items);
reverse() 颠倒数组中元素的顺序
语法:a.reverse()
返回值:元素颠倒顺序后的原数组。
example:
var a = [1,2,3,4];
a.reverse();
console.log(a); // [4, 3, 2, 1]
二、不改变原始数组的方法(6个)
let a = [1,2,3,4];
【ES5】a.slice()/ a.join()/ a.cancat()
a.indexOf()/ a.lastIndexOf()
【ES7】a.includes()
slice() 浅拷贝数组
语法:a.slice(start,end)
参数:
start:可选。规定从何处开始选取。如果是负数,那么它规定从数组尾部开始算起的位置。也就是说,-1 指最后一个元素,-2 指倒数第二个元素,以此类推。
ele2:可选。规定从何处结束选取。该参数是数组片断结束处的数组下标。如果没有指定该参数,那么切分的数组包含从 start 到数组结束的所有元素。如果这个参数是负数,那么它规定的是从数组尾部开始算起的元素。
返回值:返回一个从 start 到 end (不包括)的新数组。
example_1: 基础数据类型,拷贝后互不干扰
var a = [1,2,3];
var b = a.slice();
a.push(4);
console.log(a,b);// [1, 2, 3, 4]?[1, 2, 3]
var c = a.slice(0,2);
console.log(a,c); // [1, 2, 3, 4]?[1, 2]
var d = a.slice(-2);
console.log(a,d); // [1, 2, 3, 4]?[3, 4]
var e = a.slice(-3,-1);
console.log(a,e); // [1, 2, 3, 4]?[2, 3]
example_2: 复杂数据类型(数组、对象),仅拷贝地址,会互相影响
var a = [{"name": "Tom"},{"name": "Jerry"}];
var b = a.slice();
console.log(a,b); // [{"name": "Tom"},{"name": "Jerry"}] [{"name": "Tom"},{"name": "Jerry"}]
// a[0].name = "Sali";
// console.log(a,b); // [{"name": "Sali"},{"name": "Sali"}]
join() 数组转字符串
语法:a.join(separator)
参数:
separator:可选。指定要使用的分隔符。如果省略该参数,则使用逗号作为分隔符。
返回值:返回一个字符串。
example:
var a = [1,2,3,4];
var b = a.join();
console.log(b); // 1,2,3,4
var c = a.join('.');
console.log(c); // 1.2.3.4
var a2 = [[1,2],3,4];
var b2 = a2.join(); // 在元素是数组时,会对该元素数组继续执行 join() 的方法,如果是对象,对象会被转会为[Object Object]
console.log(b2); // 1,2,3,4
concat() 连接两个或多个数组
语法:a.concat(arrayX,arrayX,…,arrayX)
参数:
arrayX:必需。该参数可以是具体的值 or 数组 or 任意多个。
返回值:返回一个新的数组。
example:
var a = [1,2,3,4];
var b = a.concat(5,6); // 具体的值
console.log(a,b); // [1, 2, 3, 4]?[1, 2, 3, 4, 5, 6]
var c = [5,6];
var d = a.concat(c); // 数组
console.log(a,d); // [1, 2, 3, 4]?[1, 2, 3, 4, 5, 6]
var e = a.concat('加1',c,'加2');// 多个
console.log(e); // [1, 2, 3, 4, "加1", 5, 6, "加2"]
indexOf() 查找数组是否存在某个元素
语法:a.indexOf(searchElement,fromIndex)
参数:
searchElement:必需。被查找的元素。
fromIndex: 可选。开始查找的位置(不能大于等于数组的长度,返回-1),默认值为0
返回值:返回在数组中找到的给定元素的第一个索引,如果不存在,则返回-1。
注意:indexOf()使用严格相等===搜索元素,即数组元素要完全匹配才能搜索成功,不能识别NaN
example:
var a = ['哈哈哈',1,2,NaN];
console.log(a.indexOf('哈')); // -1
console.log(a.indexOf('哈哈哈')); // 0
console.log(a.indexOf('NaN')); // -1
lastIndexOf() 查找指定元素在数组中的最后一个位置
语法:a.lastIndexOf(searchElement,fromIndex)
参数:
searchElement:必需。被查找的元素。
fromIndex: 可选。
情况一:正值。如果该值大于或等于数组的长度,则整个数组会被查找。
情况二:负值。将其视为从数组末尾向前的偏移。(比如-2,从数组最后第二个元素开始往前查找)
情况三:负值。其绝对值大于数组长度,则方法返回 -1,即数组不会被查找。
返回值:返回在数组中找到的给定元素的最后一个的索引,如果不存在,则返回-1。
注意:indexOf()使用严格相等===搜索元素,即数组元素要完全匹配才能搜索成功,不能识别NaN。
example:
var a = ['OB',4,'Koro1',1,2,'Koro1',3,4,5,'Koro1']; // 数组长度为10
var b = a.lastIndexOf('Koro1',4); // 从下标4开始往前找 返回下标 2
var b = a.lastIndexOf('Koro1',100); // 大于或数组的长度 查找整个数组 返回 9
var b = a.lastIndexOf('Koro1',-11); // -1 数组不会被查找
var b = a.lastIndexOf('Koro1',-9); // 从第二个元素4往前查找,没有找到 返回 -1
includes() 查找数组是否包含某个元素【推荐替代 indexOf() 】
语法:a.includes(searchElement,fromIndex)
参数:
searchElement:必需。被查找的元素。
fromIndex: 可选。从该索引处开始查找 searchElement。如果为负值,则按升序从 array.length + fromIndex 的索引开始搜索。默认为 0。
返回值:返回一个布尔值。
example:
var a = ['哈哈哈',1,2,NaN];
console.log(a.includes('哈')); // false
console.log(a.includes('哈哈哈')); // true
console.log(a.includes('NaN')); // true 识别NaN
console.log(a.includes('哈哈哈',100)); // false 超过数组长度不搜索
三、遍历方法(6个)
let a = [1,2,3,4];
【ES5】a.every()/ a.some()
a.filter()/ a.map()
【ES6】a.find()/ a.findIndex()
语法:a.XXX(function(currentValue,index,arr), thisValue)
参数:数组遍历方法相同
function(currentValue,index,arr):必需。回调函数
currentValue:必须。当前元素的值
index: 可选。当前元素的索引值
arr: 可选。当前元素属于的数组对象
thisValue: 可选。当执行回调函数时this绑定对象的值,默认值为undefined
every() 检测数组所有元素是否都符合判断条件【返回布尔值】
返回值:如果所有元素都通过检测返回 true,否则返回 false,且剩余的元素不会再进行检测。
example:
var a = [1,2,3,4];
a.every(x => x>2); // false
a.every(x => x>0); // true
some() 检测数组中的是否有满足判断条件的元素【返回布尔值】
返回值:如果有一个元素满足条件,则表达式返回true , 剩余的元素不会再执行检测。如果没有满足条件的元素,则返回false。
example:
var a = [1,2,3,4];
a.some(x => x>2); // true
a.some(x => x>5); // false
filter() 过滤原始数组,返回新数组【原始数组中符合筛选条件的元素】
返回值:返回新数组,包含了符合条件的所有元素。如果没有符合条件的元素则返回空数组。
example_1:筛选排除所有较小的值
var data = [1, 2, 3, 4];
var arrayOfSquares = data.filter(item =>{
return item > 1;
});
console.log(arrayOfSquares); // [2,3,4]
example_2:根据条件过滤数组内容
var users = [
{name: "张一", "email": "zhang@email.com"},
{name: "江二", "email": "jiang@email.com"},
{name: "李三", "email": "li@email.com"},
{name: "王二", "email": "wang@email.com"}
];
var userArr = users.filter(item =>{return item.name.indexOf('二')>-1});
console.log(userArr); // [{name: "江二", "email": "jiang@email.com"},{name: "王二", "email": "wang@email.com"}];
map() 遍历原始数组,返回新数组【原始数组元素调用函数处理后的值】
返回值:返回新数组,数组中的元素为原始数组元素调用函数处理后的值。
example_1:原数组被“映射”成对应新数组
var data = [1, 2, 3, 4];
var arrayOfSquares = data.map(function (item) {
return item * item;
});
console.log(arrayOfSquares); // [1, 4, 9, 16]
example_2:获得数组中的特定属性值
var users = [
{name: "张一", "email": "zhang@email.com"},
{name: "江二", "email": "jiang@email.com"},
{name: "李三", "email": "li@email.com"}
];
var emails = users.map(function (user) { return user.email; });
console.log(emails); // [zhang@email.com, jiang@email.com, li@email.com]
example_3:向数组新增属性
var users = [
{name: "张一", "email": "zhang@email.com"},
{name: "江二", "email": "jiang@email.com"},
{name: "李三", "email": "li@email.com"}
];
users = users.map(function (user,index) {
user.index = index;
return user;
});
console.log(JSON.stringify(users)); // [{"name":"张一","email":"zhang@email.com","index":0},{"name":"江二","email":"jiang@email.com","index":1},{"name":"李三","email":"li@email.com","index":2}]
find() 找出第一个符合条件的数组成员【返回数组成员】
返回值:第一个符合条件的数组成员,并返回该成员,如果没有符合条件的成员,则返回undefined。
备注: 和 map() 的区别,找到一个符合条件的数组成员后不会再继续遍历数组
example:
// 数组元素是基本类型
var a = [1,2,3,4];
a.find(x => x>2); // 3
a.find(x => x>6); // undefined
// 数组元素是对象
var users = [
{name: "张一", "email": "zhang@email.com"},
{name: "江二", "email": "jiang@email.com"},
{name: "李三", "email": "li@email.com"}
];
var user = users.find(item => {
return item.name === "张一"
});
console.log(user); // {name: "张一", email: "zhang@email.com"}
findIndex() 找出第一个符合条件的数组成员的位置
返回值:第一个符合条件的数组成员的位置,如果所有成员都不符合条件,则返回-1。
example:
var a = [1,2,3,4];
a.findIndex(x => x>2); // 2
a.findIndex(x => x>6); // -1
四、实际应用
数组的交集、并集、差集、补集
const arrA = [1,2,3,4,5,5,6],
arrB = [5,6,6,7,8,9],
_arrA = Array.from(new Set(arrA)),
_arrB = Array.from(new Set(arrB));
/*数组交集:
* 1、生成2个去重的数组_arrA、 _arrB
* 2、数组_arrA去过滤【数组_arrA的元素在数组_arrB中存在】
*/
const intersection = (_arrA, _arrB) => {
return _arrA.filter(item => _arrB.includes(item));
}
console.log(intersection(_arrA,_arrB)); // [5,6]
/*数组并集:
* 1、扩展操作符展开数组arrA, arrB
* 2、用Set() 方法去重,用Array.from()将Set() 对象转成数组
*/
const union = (arrA, arrB) => {
return Array.from(new Set([...arrA, ...arrB]));
}
console.log(union(arrA, arrB)); // [1, 2, 3, 4, 5, 6, 7, 8, 9]
/* 数组差集arrA-arrB:
* 数组arrA去过滤【数组arrA的元素在数组arrB中不存在】
*/
const diff = (arrA, arrB) => {
return arrA.filter(item => !arrB.includes(item));
}
console.log(diff(arrA, arrB)); // [1, 2, 3, 4]
/* 数组补集: 2者差集之和
*/
const complement = (arrA, arrB) => {
return diff(arrA, arrB).concat(diff(arrB, arrA));
}
console.log(complement(arrA, arrB)); // [1, 2, 3, 4, 7, 8, 9]