2021系列——JavaScript比较数组的7种方法
myzbx 2025-07-02 23:17 12 浏览
本文我会介绍一些基于Property值对数组进行排序的方法,希望这些技巧能够对你2021年的JS代码编写有点点帮助。
多多少少在JS中,我们会碰到某种方式来比较两个对象数组并找出差异,当然也可能是比较并删除重复项,还可能是比较两个对象数组并更新对象数组的属性,再有可能呢,是需要比较两个对象数组后使用唯一数据创建一个新数组。
下面让我们看看比较对象和执行操作的不同方法。
1 . 比较两个对象数组,删除重复项,根据属性合并对象
工作中存在这样的情况,需要比较下两个不同的对象数组,而且如果两个对象匹配特定的属性值,则希望合并这两个对象。可以使用过滤方法来实现:
用filter()方法创建一个新数组,其中所有元素都通过了以该函数为条件实现的测试。可查看来源,
相关链接:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
我们先创建测试数据,
let array1 = [
{ id: "50", active: "a", value: 10 },
{ id: "51", active: "a", value: 11 }
];
let array2 = [
{ id: "53", active: "a", value: 10 },
{ id: "51", active: "a", value: 11 },
{ id: "52", active: "a", value: 13 }
];
再创建函数,
let res = array2.filter(val =>
array1.some(({
value
}) => (val.value as any) === (value as any))
);
console.log("1", JSON.stringify(res));
//[{"id":"53","active":"a","value":10},
{"id":"51","active":"a","value":11}]
2 . 比较两个对象数组,合并和更新值(假设数组3,4共享相同的ID)
有时我们被要求将两个不同的属性与新的属性值合并;我们可以使用map创建一组新的对象数组,同时使用find方法在更新新值之前匹配特定属性。
该map()方法创建一个新数组,其中填充了在调用数组中每个元素上调用一个以函数为条件的结果。
该find()方法返回所提供的数组中满足以测试函数为条件的第一个元素的值。如果没有值满足测试函数,则undefined会被返回。可查看来源,
相关链接:
https://developer.mozilla.org/en-US/docs/Web/JavaScript
先创建测试数据,
let array3 = [
{ id: "50", active: "a", value: 12 },
{ id: "51", active: "a", value: 15 }
];
let array4 = [
{ id: "50", active: "a", value: 10 },
{ id: "51", active: "a", value: 11 },
{ id: "52", active: "a", value: 13 }
];
让我们来创建函数,
let arr = [];
array3.map(id =>
arr.push({
id: id.id,
newValue: array4.find(o => o.id === id.id).value + 2
})
);
console.log("2", JSON.stringify(arr));
//[{"id":"50","newValue":12},{"id":"51","newValue":13}]
3 . 比较对象数组并找到唯一的对象
如果我们需要比较两个对象数组,并检查其中哪些是唯一对象,则可以使用过滤器来实现这些功能。
仍旧先创建测试数据,
const array5 = [
{ id: "50", active: "a", value: 12 },
{ id: "51", active: "a", value: 15 }
];
const array6 = [
{ id: "50", active: "a", value: 12 },
{ id: "51", active: "a", value: 15 },
{ id: "52", active: "a", value: 13 }
];
再创建函数,
const ids = array5.map(e => e.id);
let filtered = array6.filter(e => ids.includes(e.id));
console.log("3", JSON.stringify(filtered));
//[{"id":"50","active":"a","value":12},
{"id":"51","active":"a","value":15}]
4 . 根据匹配的值比较和更新属性
当我们需要比较两个对象数组,并根据匹配的值更新特定属性时,可以使用这些函数。
创建测试数据,
const array7 = [
{ id: "50", active: "a", value: 12 },
{ id: "51", active: "a", value: 15 }
];
const array8 = [{ id: "50", active: "a", value: 12 }];
创建函数,
const idSet = new Set(array8.map(o => o.id));
const res1 = array7.map(o => ({ ...o, value: idSet.has(o.id) ? "0" :
o.value }));
console.log("4", JSON.stringify(res1));
//[{"id":"50","active":"a","value":"0"},
{"id":"51","active":"a","value":15}]
5 . 比较两个数组对象并获得差异
当我们要比较两个不同的对象数组并得到它们之间的差异时,可以使用这些函数。
创建测试数据
let a = [
{ id: "50", active: "a", value: 10 },
{ id: "51", active: "a", value: 11 }
];
let b = [
{ id: "50", active: "a", value: 10 },
{ id: "51", active: "a", value: 11 },
{ id: "52", active: "a", value: 13 }
];
创建函数
let valuesArray1 = a.reduce(function(a, c) {
a[c.value] = c.value;
return a;
}, {});
let valuesArray2 = b.reduce(function(a, c) {
a[c.value] = c.value;
return a;
}, {});
var result = a
.filter(function(c) {
return !valuesArray2[c.value];
})
.concat(
b.filter(function(c) {
return !valuesArray1[c.value];
})
);
console.log("5", result);
//[{"id":"52","active":"a","value":13}]
//shorthand
let ab = b.filter(o => !a.find(o2 => o.id === o2.id));
console.log("6", ab);
6 . 比较对象的两个数组合并,并删除重复项
如果我们需要比较两个对象数组,从它们中删除重复项,并合并两个数组,则可以使用此方法。
创建测试数据,
let arr1 = [
{ id: "50", active: "a", value: 10 },
{ id: "51", active: "a", value: 11 }
];
let arr2 = [
{ id: "50", active: "a", value: 10 },
{ id: "51", active: "a", value: 11 },
{ id: "52", active: "a", value: 13 }
];
创建函数,
const arr1IDs = new Set(arr1.map(({ id }) => id));
const combined = [...arr1, ...arr2.filter(({ id }) =>
!arr1IDs.has(id))];
console.log(JSON.stringify(combined));
//[{"id":"50","active":"a","value":10},
{"id":"51","active":"a","value":11},
{"id":"52","active":"a","value":13}]
7 . Lodash
Lodash支持_differenceBy和 _differenceWith查找两个数组之间差异的方法。
let lodashtest1 = [{ id: "50" }, { id: "51" }];
let lodashtest2 = [{ id: "50" }, { id: "51" }, { id: "52" }];
let lodashresult = _.differenceBy(lodashtest2, lodashtest1, "id");
console.log("7", JSON.stringify(lodashresult));
//[{"id":"52"}]
let dif = _.differenceWith(lodashtest2, lodashtest1, _.isEqual);
console.log("8",JSON.stringify(dif));
//[{"id":"52"}]
8 . 好吧来个7+1,比较对象并找到唯一值
当我们使用嵌套对象时,有时很难弄清楚我们如何迭代和比较两个嵌套对象并在其中获得一些唯一的对象。我们可以使用Object.keys和Object.values方法进行迭代。
创建测试数据,
let obj1 = {
val1: "test",
stream: { prop1: false, prop2: true }
};
let obj2 = {
val1: "test",
stream: { prop1: true, prop2: true }
};
interface Data {
stream: { [key: string]: boolean };
}
创建函数:
function objFilter(objA: Data, objB: Data): Data {
let out: Data = { stream: {} };
Object.keys(objA.stream).filter((value, idx) =>
Object.values(objA.stream)[idx] === Object.values(objB.stream)[idx]
? (out.stream[value] = Object.values(objA.stream)[idx])
: false
);
return out;
}
console.log(JSON.stringify(objFilter(obj1, obj2))); //prop2
//{"stream":{"prop2":true}}
另外,再送小礼,推荐下StackBlitz,它是一款主要面向 Web 开发者的在线 IDE,移植了很多 VS Code 的特性与功能,非常的方便易用。
相关链接:
https://stackblitz.com/edit/compare-objects-javascript
相关推荐
- 掌握JavaScript中的Call和Apply,让你的代码更强大、更灵活
-
在学习JavaScript时,你可能会遇到call和apply这两个方法。它们的作用其实很相似,都是用来调用函数并设置函数内部的this值,但它们的使用方式稍有不同。想象一下,你和朋友们一起拍照。ca...
- 性能调优方面,经常要优化跑的最慢的代码,教你一种快速的方法
-
在我们遇到性能问题的时候,很多时候需要去查看性能的瓶颈在哪里,本篇文章就是提供了多种常用的方案来监控函数的运行时间。1.time首先说明,time模块很多是系统相关的,在不同的OS中可能会有一些精度差...
- call和apply的实现方式_call和apply用法
-
call和apply的实现方式1、函数Function.call()的实现//第一步简单是实现call()varfoo={value:”1”,bar:function(){conso...
- 线上问题排查:接口超时_接口超时时间设置多少合适
-
最近就看到了一个非常厉害的关于“接口超时”问题排查的帖子,从应用排查到内核级别。虽然看到后面的时候我已经有点跟不上了,但是对于整个问题排查的过程还是比较清晰的。(细节不重要,排查思路,方向值得学习)问...
- javascript中的call方法的另一种实现方式-更接近原方法
-
上集我们说到对应的我们自己实现的call方法还是有一点纰漏,这里我们就解决它//一、预备知识(简单介绍)//1、Function.prototype.call()//语法:function....
- 链接器是如何一步步发明出来的?_如何使用连接器
-
在计算机编程的早期年代,你面临一个挥之不去的的噩梦。。。你找了一个刚刚运行成功的程序仔细看了看:; main.asm - 主程序start: &nb...
- Day59:回调(callback)函数_回调 callback
-
定义Acallbackisafunctionthatispassedasanargumenttoanotherfunctionandisexecutedafteri...
- 大促数据库压力激增,如何一眼定位 SQL 执行来源?
-
作者:京东科技王奕龙你是否曾经遇到过这样的情况:在大促活动期间,用户访问量骤增,数据库的压力陡然加大,导致响应变慢甚至服务中断?更让人头疼的是,当你试图快速定位问题所在时,却发现难以确定究竟是哪个业...
- 一键追欠料!WPS表格实战MRP欠料计算-7
-
昨天第6章内容主要聚焦于本报表的核心欠料运算。通过子件库存的引用以及累计需求的计算,计算出了子件的累计欠料。累计欠料的显示方式是按日期进行逐日累加,并不能清晰的看到每张订单欠料多少?所以在今日第7章的...
- Python教程(二十五):装饰器–函数的高级用法
-
今天您将学习什么什么是装饰器以及如何创建装饰器函数装饰器和类装饰器带参数的装饰器装饰器的实际应用真实世界示例:日志记录、性能监控、缓存、权限验证什么是装饰器?装饰器是Python中的一种...
- 在 Excel 日历制作中,尤其是动态日历方案,会用到的多个函数详解
-
在Excel日历制作中,尤其是动态日历方案,会用到多个核心函数。下面我将详细解析这些函数的作用、参数和使用技巧:核心日期函数1.DATE(year,month,day)作用:创建指定日期参...
- java高级用法之:在JNA中将本地方法映射到JAVA代码中
-
简介不管是JNI还是JNA,最终调用的都是native的方法,但是对于JAVA程序来说,一定需要一个调用native方法的入口,也就是说我们需要在JAVA方法中定义需要调用的native方法。对于JN...
- 14.4 查找与引用函数综合应用 - 下
-
一、使返回错误值以简化公式例提取一二三级科目名称在下图所示的科目代码表中,A列为科目代码,B列为对应科目名称。A列科目代码中长度为4的为一级代码,长度为6的为二级代码,长度为8的为三级代码。要求根据...
- 记一次酣畅淋漓的JavaScript逆向_js逆向webpack
-
背景介绍今天在写爬虫的练习题时遇到了这样一个难题:目标资源是一个图片的url,但是不同于以往的情况,我在http响应记录里搜索这个图片的url,发现并不能搜到。从逻辑上来讲,这个url被展示到浏览器上...
- 「Postman」测试(Tests)脚本编写和断言详解
-
测试确认您的API按预期工作,服务之间的集成运行可靠,并且新开发没有破坏任何现有功能。您可以使用JavaScript为PostmanAPI请求编写测试脚本。当您的API项目出现问题时...
- 一周热门
- 最近发表
- 标签列表
-
- HTML 简介 (30)
- HTML 响应式设计 (31)
- HTML URL 编码 (32)
- HTML Web 服务器 (31)
- HTML 表单属性 (32)
- HTML 音频 (31)
- HTML5 支持 (33)
- HTML API (36)
- HTML 总结 (32)
- HTML 全局属性 (32)
- HTML 事件 (31)
- HTML 画布 (32)
- HTTP 方法 (30)
- 键盘快捷键 (30)
- CSS 语法 (35)
- CSS 轮廓宽度 (31)
- CSS 谷歌字体 (33)
- CSS 链接 (31)
- CSS 定位 (31)
- CSS 图片库 (32)
- CSS 图像精灵 (31)
- SVG 文本 (32)
- 时钟启动 (33)
- HTML 游戏 (34)
- JS Loop For (32)