让我们拥有一个具有默认设置的对象:
var defaults = {
id: '',
x: 0,
y: 0,
width: 20,
height: 20,
styles: {
color: '#ffffff',
background_color: '#000000'
},
points: []
}
然后,我们创建自己的对象,它最初扩展了默认设置,并进行了一些更改:
var newObject = {
id: '1', // changed
x: 10, // changed
y: 10, // changed
width: 20,
height: 20,
styles: {
color: '#ffffff',
background_color: '#333333' // changed
},
points: [1, 2, 3]
}
最后,我们需要一个对象,它只包含从默认设置更改的值,如下所示:
var subtracted = {
id: '1',
x: 10,
y: 10,
styles: {
background_color: '#333333'
},
points: [1, 2, 3]
}
算法需要递归,对象中可以有对象。以下是我到目前为止的情况:
function subtract(a, b) {
var r = {};
// For each property of 'b'
// if it's different than the corresponding property of 'a'
// place it in 'r'
for (var key in b) {
if (typeof(b[key]) == 'object') {
if (!a[key]) a[key] = {};
r[key] = subtract(a[key], b[key]);
} else {
if (b[key] != a[key]) {
r[key] = a[key];
}
}
}
return r;
}
但是,递归不适用于数组,所以" points"原来是一个空物体! typeof()将其检测为对象,无法以某种方式克隆其属性。
答案 0 :(得分:2)
您的代码正常运行。虽然我有一个编辑,使其也递归。
CREATE TABLE [dbo].[Receipt] (
[receiptID] INT IDENTITY (1, 1) NOT NULL,
[employeeUser] NVARCHAR (50) NULL,
[purchasedProductID] INT NULL,
[productName] NVARCHAR (50) NULL,
[clientID] INT NULL,
PRIMARY KEY CLUSTERED ([receiptID] ASC)
答案 1 :(得分:1)
更新:另一种递归方法。它通过修改运行,因此newObject可以忽略某些字段。它也适用于基元。
const equalArrays = (arr1, arr2) => arr1.length === arr2.length && arr1.every((element, index) => element === arr2[index])
// notice that equalArrays matters the order of the arrays' elements.
// If order doesn't matter, consider sorting both arrays first
const isObject = (obj) => obj instanceof Object && !(obj instanceof Array)
// notice that arrays are instance of Objects too
// an unwary consumer might mix arrays and objects with unpredictable results
const isArray = (arr) => arr instanceof Array
const getDifferences = (original, modified) => {
const areArrays = isArray(original) && isArray(modified)
const areObjects = isObject(original) && isObject(modified)
if (areObjects) {
let result = {}
for (const key of Object.keys(modified)) {
const diff = getDifferences(original[key], modified[key])
if (diff) result[key] = diff
}
return !!Object.keys(result).length && result
}
else if (areArrays && !equalArrays(original, modified)) return modified
else if (original !== modified) return modified
}
// notice that some variables and functions are there for readability and might be inlined
let defaults = {
id: '',
x: 0,
y: 0,
width: 20,
height: 20,
styles: {
color: '#ffffff',
background_color: '#000000'
},
points: []
}
let newObject = {
id: '1', // changed
x: 10, // changed
y: 10, // changed
width: 20,
height: 20,
styles: {
color: '#ffffff',
background_color: '#333333' // changed
},
points: [0, 1, 2] // changed
}
console.log(getDifferences(defaults, newObject))
我会考虑到一些粗心的消费者可能会混合使用数组和对象。
const equalArrays = (arr1, arr2) => arr1.length === arr2.length && arr1.every((element, index) => element === arr2[index])
// notice that equalArrays matters the order of the arrays' elements.
// If order doesn't matter, consider sorting both arrays first
const isObject = (obj) => obj instanceof Object && !(obj instanceof Array)
// notice that arrays are instance of Objects too
// an unwary consumer might mix arrays and objects with unpredictable results
const isArray = (arr) => arr instanceof Array
const getDifferences = (obj1, obj2) => {
let obj3 = {}
for (const key of Object.keys(obj1)) {
const val1 = obj1[key]
const val2 = obj2[key]
const areArrays = isArray(val1) && isArray(val2)
const areObjects = isObject(val1) && isObject(val2)
if (areObjects) {
const diff = getDifferences(val1, val2)
if (diff) obj3[key] = diff
}
else if (areArrays && !equalArrays(val1, val2)) obj3[key] = val2
else if (val1 !== val2) obj3[key] = val2
}
return !!Object.keys(obj3).length && obj3
}
// notice that some variables and functions are there for readability and might be inlined
let defaults = {
id: '',
x: 0,
y: 0,
width: 20,
height: 20,
styles: {
color: '#ffffff',
background_color: '#000000'
},
points: []
}
let newObject = {
id: '1', // changed
x: 10, // changed
y: 10, // changed
width: 20,
height: 20,
styles: {
color: '#ffffff',
background_color: '#333333' // changed
},
points: [0, 1, 2] // changed
}
console.log(getDifferences(defaults, newObject))