比较两个对象的键并构造具有相同键的第三个键来反映差异

时间:2016-03-31 14:56:43

标签: javascript

我试图比较两个对象,如果存储在一个属性中的值与另一个属性不同,则构造第三个对象。如果不是我存储空字符串。在我看来,这样做的方式是效率极低且不可持续。如果按键改变或数量增加,这将不起作用。我必须能够以编程方式使用纯JS,没有jQuery:

var staleProfile = {
  firstName: 'john',
  lastName: 'smith',
  email: 'js@gmail.com'
}

var CurrentCustomer = {};

CurrentCustomer.profile = {
  firstName: 'paul',
  lastName: 'smith',
  email: 'js@yahoo.com'
}

var returnObj = {};

returnObj.firstName = staleProfile.firstName != CurrentCustomer.profile.firstName ? CurrentCustomer.profile.firstName : ''
returnObj.lastName = staleProfile.lastName != CurrentCustomer.profile.lastName ? CurrentCustomer.profile.lastName : ''
returnObj.email = staleProfile.email != CurrentCustomer.profile.email ? CurrentCustomer.profile.email : ''  

3 个答案:

答案 0 :(得分:0)

一种方法是创建一个小辅助函数来分配每个属性(或空字符串):

// NOTE: staleProfile and CurrentCustomer are assumed to be in the scope above
// If this could be an issue, just pass them as parameters
function getProp(prop) {
  let staleProp = staleProfile[prop];
  let currProp = CurrentCustomer.profile[prop];
  return staleProp != currProp ? currProp : '';
}

然后使用它:

let returnObj = {
  firstName : getProp('firstName'),
  lastName  : getProp('lastName'),
  email     : getProp('email')
}

运行示例

var staleProfile = {
  firstName: 'john',
  lastName: 'smith',
  email: 'js@gmail.com'
}

var CurrentCustomer = {};

CurrentCustomer.profile = {
  firstName: 'paul',
  lastName: 'smith',
  email: 'js@yahoo.com'
}

function getProp(prop) {
  let staleProp = staleProfile[prop];
  let currProp = CurrentCustomer.profile[prop];
  return staleProp != currProp ? currProp : '';
}

let returnObj = {
  firstName: getProp('firstName'),
  lastName: getProp('lastName'),
  email: getProp('email')
}

console.log(returnObj);

这个帮助函数的优点是,如果您需要更新替换缺失值的策略,您只需要在一个地方完成。

此外,您可能需要提取一系列密钥:

let keys = ['firstName', 'lastName', 'email'];

或者也许使用Object.keys提取所有内容:

let keys = Object.keys(staleProfile);

然后您可以使用getProp功能存储密钥:

keys.forEach(k => {
  returnObj[k] = getProp(k);
});

这将使添加/删除属性仅仅是keys数组的当前内容。当您需要删除或添加属性时,您可以在第一个示例中更新keys数组,或者在第二个示例中更新staleProfile并让Object.keys为您返回值。无论哪种方式,通过一个小的更改,您可以添加/删除属性。

运行示例:

var staleProfile = {
  firstName: 'john',
  lastName: 'smith',
  email: 'js@gmail.com'
}

var CurrentCustomer = {};

CurrentCustomer.profile = {
  firstName: 'paul',
  lastName: 'smith',
  email: 'js@yahoo.com'
}

function getProp(prop) {
  let staleProp = staleProfile[prop];
  let currProp = CurrentCustomer.profile[prop];
  return staleProp != currProp ? currProp : '';
}

let keys = Object.keys(staleProfile);
let returnObj = {};

keys.forEach(k => {
  returnObj[k] = getProp(k);
});

console.log(returnObj);

注意 James Thorpe 在评论中做了很好的观察。

  

如果您说的未来某个属性可以有效地保留空字符串怎么办?在这种情况下,您将不知道它是否已更新为空字符串或未更改。您可能要考虑对未更改的项使用null

答案 1 :(得分:0)

选项是使用keys获取对象中的所有Object.keys(staleProfile)

在此之后,您可以遍历键并比较值。请参阅下面的示例。

var keys = Object.keys(staleProfile),
    i, j,
    comparedObject = {},
    key,
    CurrentCustomer = {
       a:a,
       b:b,
       c:c
    };

for (i = 0, j = keys.length; i < j; i++) {
    key = keys[i];

    if (staleProfile[key] === CurrentCustomer[key]) {
        comparedObject[key] === CurrentCustomer[key];
    } else {
        comparedObject[key] === '';
    }
}

答案 2 :(得分:0)

这将搜索CurrentCustomer.profile中的所有对象键,并检查与staleProfile的差异。它为差异添加了关键字,仅存在于object1但不存在于object0中,但不会处理从object0移至object1的关键字。< / p>

var staleProfile = {
    firstName: 'john',
    lastName: 'smith',
    email: 'js@gmail.com',
    key0: 'value0'
}

var CurrentCustomer = {};

CurrentCustomer.profile = {
    firstName: 'paul',
    lastName: 'smith',
    email: 'js@yahoo.com',
    key1: 'value1'
}

function createDiffObject(object0, object1) {
    var diff = {};
    Object.keys(object1).forEach(function(key) {
        if (!object0.hasOwnProperty(key) || object0[key] != object1[key]) {
            diff[key] = object1[key];
        } else {
            diff[key] = '';
        }
    });
    return diff;
}

console.log(createDiffObject(staleProfile, CurrentCustomer.profile));
// output:
/*
{ firstName: 'paul',
  lastName: '',
  email: 'js@yahoo.com',
  key1: 'value1' }
*/