第一个数组对象,有些没记录电话
const oldList = [ { department: '部门1', name: '姓名1', phone: '11111'}, { department: '部门2', name: '姓名2', phone: '22222' }, { department: '部门3', name: '姓名3' }];
第二个数组对象,有一些改动
const newList = [ { department: '部门2', name: '姓名2', phone: '77777' }, { department: '部门3', name: '姓名3', phone: '88888' }, { department: '部门4', name: '姓名4', phone: '99999' }];
想要得到一个电话变动情况表:
const changeList = [ { department: '部门1', name: '姓名1', change:'旧号码11111新号码(空)' }, { department: '部门2', name: '姓名2', change:'旧号码22222新号码77777' }, { department: '部门3', name: '姓名3', change:'旧号码(空)新号码88888' }, { department: '部门4', name: '姓名4', change:'旧号码(空)新号码99999' }]
Object.values([old, new_].reduce((obj, arr, idx) => arr.reduce((obj, {phone, ...rest}) => { ((obj[rest.name] ??= rest).phone ??= [])[idx] = phone; return obj; }, obj), {})).map(({phone: [old, new_], ...rest}) => ({ ...rest, change: `旧号码${old ?? '(空)'}新号码${new_ ?? '(空)'}`}))
啊,读题错误……正确的是借助 Array.reduce() 即可,因为你需要的是一个展示变更操作的结果。
const oldList = [ { department: '部门1', name: '姓名1', phone: '11111'}, { department: '部门2', name: '姓名2', phone: '22222' }, { department: '部门3', name: '姓名3' }];const newList = [ { department: '部门2', name: '姓名2', phone: '77777' }, { department: '部门3', name: '姓名3', phone: '88888' }, { department: '部门4', name: '姓名4', phone: '99999' }];// 修改记录列表, 因为可能修改时会删除一些记录,所以展开了新旧数据一起循环。// 因为需要先填入旧数据,所以先展开 oldList,然后展开 newList。const changeList = [...oldList, ...newList].reduce((changeList, currentData) => { // 是否已经添加到修改记录列表中,如果已经添加则返回添加了的记录。 const added = changeList.find(data => data.name === currentData.name) // 如果已经添加过了,则开始设置 newPhone 属性 if(added) { added.newPhone = currentData.phone } else { // 如果没有修改则添加到修改列表中 // 因为担心修改源数据会造成一些其它的业务问题,所以这边添加时做了浅拷贝。 changeList.push({ ...currentData, newPhone: '' }) } return changeList}, [])// 获得的变更记录// (4) [{…}, {…}, {…}, {…}]// 0: {department: '部门1', name: '姓名1', phone: '11111', newPhone: ''}// 1: {department: '部门2', name: '姓名2', phone: '22222', newPhone: '77777'}// 2: {department: '部门3', name: '姓名3', newPhone: '88888'}// 3: {department: '部门4', name: '姓名4', phone: '99999', newPhone: ''}// length: 4
这个时候修改记录列表中已经有了所有的人员记录,以及他们各自的新旧电话号码,因为你最终要还需要有一个 change
属性来记录变更内容,所以再借助 Array.map() 来处理组装即可:
const changeResultList = changeList.map(data => { return { ...data, change: `旧号码:${data.phone || '(空)'},新号码:${data.newPhone || '(空)'}` }})// 获得的变更结果记录// (4) [{…}, {…}, {…}, {…}]// 0: {department: '部门1', name: '姓名1', phone: '11111', newPhone: '', change: '旧号码:11111,新号码:(空)'}// 1: {department: '部门2', name: '姓名2', phone: '22222', newPhone: '77777', change: '旧号码:22222,新号码:77777'}// 2: {department: '部门3', name: '姓名3', newPhone: '88888', change: '旧号码:(空),新号码:88888'}// 3: {department: '部门4', name: '姓名4', phone: '99999', newPhone: '', change: '旧号码:99999,新号码:(空)'}// length: 4
其实也可以在 reduce
循环的时候一起处理掉,但是我怕OP你不好理解,所以拆分成两步,最后又 map
循环拼接了一次数据。
如果不想多一次 map
操作,可以像下面这样修改 reduce
的代码,就可以一次性全部处理好了。
const changeList = [...oldList, ...newList].reduce((changeList, currentData) => { const added = changeList.find(data => data.name === currentData.name) if(added) { added.newPhone = currentData.phone added.chanmge = `旧号码:${currentData.phone || '(空)'},新号码:${currentData.newPhone || '(空)'}` } else { changeList.push({ ...currentData, newPhone: '', change: `旧号码:${currentData.phone || '(空)'},新号码:(空)}` }) } return changeList}, [])
一般会借助现有的轮子,比如说 lodash
。里面就有提供各种 diff
的工具函数。
你当前的需求就是 _.differenceBy 这个函数,所以直接用就行了。
const oldList = [ { department: '部门1', name: '姓名1', phone: '11111'}, { department: '部门2', name: '姓名2', phone: '22222' }, { department: '部门3', name: '姓名3' }];const newList = [ { department: '部门2', name: '姓名2', phone: '77777' }, { department: '部门3', name: '姓名3', phone: '88888' }, { department: '部门4', name: '姓名4', phone: '99999' }];_.differenceBy(oldList, newList, 'phone');// (3) [{…}, {…}, {…}]// 0: {department: '部门1', name: '姓名1', phone: '11111'}// 1: {department: '部门2', name: '姓名2', phone: '22222'}// 2: {department: '部门3', name: '姓名3'}// length: 3
function diffData(a, b) { const phoneMap = a.reduce((res,v) => (res[v.department+v.name]=v, res),{}); return b.map(({name: n, department: d, phone: p}) => { const res = { name: n, department: d, change: `旧号码${phoneMap[d+n]?.phone || '(空)'}新号码${p}` }; delete phoneMap[d+n]; return res; }).concat( Object.values(phoneMap).map(({name, department, phone}) => ({name, department, change: `旧号码${phone}新号码(空)`})) )}
试试chatgpt给的答案是否是你想要的
const oldData = [ { department: '部门1', name: '姓名1', phone: '11111' }, { department: '部门2', name: '姓名2', phone: '22222' }, { department: '部门3', name: '姓名3' }];const newData = [ { department: '部门2', name: '姓名2', phone: '77777' }, { department: '部门3', name: '姓名3', phone: '88888' }, { department: '部门4', name: '姓名4', phone: '99999' }];const changeData = [];// 遍历旧数据for (let i = 0; i < oldData.length; i++) { const oldItem = oldData[i]; let found = false; // 在新数据中查找匹配项 for (let j = 0; j < newData.length; j++) { const newItem = newData[j]; // 判断是否匹配(根据部门和姓名) if (oldItem.department === newItem.department && oldItem.name === newItem.name) { found = true; // 比较电话号码是否发生变化 if (oldItem.phone !== newItem.phone) { changeData.push({ department: oldItem.department, name: oldItem.name, change: `旧号码${oldItem.phone}新号码${newItem.phone}` }); } // 退出内层循环 break; } } // 如果在新数据中未找到匹配项,则说明该记录已被删除 if (!found) { changeData.push({ department: oldItem.department, name: oldItem.name, change: `旧号码${oldItem.phone}新号码(空)` }); }}// 处理新数据中新增的记录for (let i = 0; i < newData.length; i++) { const newItem = newData[i]; let found = false; // 在旧数据中查找匹配项 for (let j = 0; j < oldData.length; j++) { const oldItem = oldData[j]; // 判断是否匹配(根据部门和姓名) if (newItem.department === oldItem.department && newItem.name === oldItem.name) { found = true; break; } } // 如果在旧数据中未找到匹配项,则说明该记录是新增的 if (!found) { changeData.push({ department: newItem.department, name: newItem.name, change: `旧号码(空)新号码${newItem.phone}` }); }}console.log(changeData);
我有一个简单的javascript问题,我真的需要一些帮助!我正在尝试弄清楚如何在数组之间比较元素,以及在下一个循环中再次比较较大的元素。假设我们有数组A和数组B。 我的问题是,在比较索引处的元素之后,我希望在下一个循环周期中比较较大的元素。 如果A=[5,7,4],B=[2,8,5] 在第一个循环中,5与2进行比较,2较小,因此会发生一些事情。在下一个循环周期中,我希望5与8进行比较,而对于现在
let arr1 = [333,555,222] let arr2 = [100,200,300] arr1 和 arr2 中的每项是对应关系, 请问如何比较 arr1中 最大值的那项,必须对应arr2中的最小值 意思就是说,按正常情况,arr1和arr2的对应关系应为: let arr1 = [333,555,222] let arr2 = [200,100,300] 请问如何去写判断?实际场景
js 比较两个数组,并进行替换掉? 需要根据arr2对象里面的val数组里面的值[200, 300, 500]去匹配arr1数组下sk数组里面的Value的值,如果arr1数组下sk数组里面的Value的值和arr2对象里面的val数组里面的值相等就替换Name,把arr2 对象的name 赋值到sk数组里面的Name 期望得到 这样写了调试了还没效果。麻烦大佬们帮我看看
问题内容: 我有这个间隔,当前每5秒执行一次ajax请求。我对声明有疑问。我的代码总是输入它,并且两个json值完全相同,为什么它认为它们不同? 编辑 这是控制台输出(虚线是分隔请求,它不在实际输出中) 问题答案: 不能保证以相同的方式序列化JSON对象,也不能保证属性以相同的顺序进行序列化,使用并不是测试对象相等性的好方法。 一个更好的例子是这样的函数(前一段时间在互联网上找到,希望我能感谢原始
问题内容: 我必须比较两个对象(不是)。比较它们的规范方法是什么? 我可以想到: 该运营商只比较基准,因此这将仅适用于较低的整数值的工作。但是也许自动装箱开始了…? 这看起来像一个昂贵的操作。是否以此方式计算出哈希码? 有点冗长… 编辑: 谢谢您的答复。尽管我现在知道该怎么办,但事实已分布在所有现有答案(甚至是已删除的答案)上,我也不知道该接受哪个答案。因此,我将接受最佳答案,即所有三种比较可能性
本文向大家介绍JavaScript 数组比较,包括了JavaScript 数组比较的使用技巧和注意事项,需要的朋友参考一下 示例 为了进行简单的数组比较,您可以使用JSON stringify并比较输出字符串: 注意:这仅在两个对象都可以JSON序列化并且不包含循环引用的情况下起作用。可能会抛出TypeError: Converting circular structure to JSON 您可以