Javascript 如何实现数据比较函数的递归?
我的应用程序中有一个助手功能,它告诉我与Javascript 如何实现数据比较函数的递归?,javascript,typescript,recursion,helper,ava,Javascript,Typescript,Recursion,Helper,Ava,我的应用程序中有一个助手功能,它告诉我与oldData相比,newData的变化 如何重构我的getChanges函数以使下面的测试通过? 我认为我可能需要使这个函数递归,因为它从自身内部执行自身,但我不完全确定如何实现它 看起来是这样的: getChangeshelper函数: export function getChanges(oldData: Record<string, any>, newData: Record<string, any>): any {
oldData
相比,newData
的变化
如何重构我的getChanges函数以使下面的测试通过?
我认为我可能需要使这个函数递归,因为它从自身内部执行自身,但我不完全确定如何实现它
看起来是这样的:
getChanges
helper函数:
export function getChanges(oldData: Record<string, any>, newData: Record<string, any>): any {
return Object.entries(newData).reduce((changes, [key, newVal]) => {
if (JSON.stringify(oldData[key]) === JSON.stringify(newVal)) return changes
changes[key] = newVal
return changes
}, {} as any)
}
index.ts测试2未通过
import test from 'ava'
import { getChanges } from '../src/comparisonHelpers.js'
test('getChanges - flat', (t) => {
const a = getChanges({}, {})
const b = {}
t.deepEqual(a, b)
t.deepEqual(getChanges({ a: 1 }, { a: 1 }), {})
t.deepEqual(getChanges({ a: 1 }, {}), {})
t.deepEqual(getChanges({}, { a: 1 }), { a: 1 })
const oldData = { a: 1, b: 1, c: 1 }
const newData = { x: 1, a: 1, b: 2 }
const result = getChanges(oldData, newData)
const expect = { x: 1, b: 2 }
t.deepEqual(result, expect)
})
import test from 'ava'
import { getChanges } from '../src/comparisonHelpers.js'
test('getChanges - nested difference', (t) => {
const oldData = { nested: { a: 1, b: 1, c: 1 } }
const newData = { nested: { x: 1, a: 1, b: 2 } }
const res = getChanges(oldData, newData)
t.deepEqual(res, { nested: { x: 1, b: 2 } })
})
基本上,如果测试通过,我不希望返回任何内容,但此测试在失败时返回此对象:
{
nested: {
- a: 1,
b: 2,
x: 1,
},
}
我在这里做错了什么,阻止了这次考试的通过
干杯 这是一个非常粗糙的函数的第一步(这里称为
diff
,而不是getChanges
):
const isObject=(o)=>
对象(o)==o
常量isEmptyObject=(o)=>
isObject(o)&&Object.keys(o).length==0
常数差=(a,b)=>
Object.fromEntries(
[…(新集合([…对象.键(a),…对象.键(b)])].flatMap(
(k) =>
k在a
?k in b
?等深线(a[k])
?等深线(b[k])
?[[k,diff(a[k],b[k])]/!isEmptyObject(v))
)
constolddata={nested:{a:1,b:1,c:1},foo:{x:3,y:5},bar:{x:1},qux:{x:6}
const newData={nested:{x:1,a:1,b:2},foo:{x:4,y:5},bar:{x:1},corge:{x:6}
console.log(diff(oldData,newData))
作为控制台包装{max height:100%!important;top:0}
您的期望值来自哪里?它是否应该包含类似于c:undefined
?我想你会从中受益。如果您有任何问题,请告诉我。@ScottSauyet谢谢您的回复!现在,这些测试与它们所在的文件完全隔离。现在,预期值是getChanges函数中的第二个值(请参阅我添加的“测试1”)。测试1将事情分解得更好一些,因为它只是寻找两者之间的差异。我希望编辑比我的文章更有意义explanation@Thankyou当前位置我一直在寻找答案。我没有找到它,只是自己写了第一篇。不过还是太难看了,无法分享。@LovelyAndy:我在想为什么你的输出中没有预期的c
?它在第一个值中,而不是在第二个值中。我希望类似于{nested:{x:1,b:2,c:undefined}}
或类似的东西。删除c
肯定是一个需要注意的变化,不是吗?但是,请看一下Thankyu的建议,它提供了一种更为强劲的风格差异。非常感谢Scott。这比我最初预期的要多得多,但老实说,这帮了大忙。我很感激你的时间,希望我能把它用在工作上!再次感谢!很好地解决了这种方法的缺点。尽管如此,这是一个很好的答案。我无法测试它,但它看起来也会将数组转换为对象。@谢谢:我也没有测试过,但我想说的是,不显式处理数组是另一个限制。