比较两个深层嵌套的对象对象,只返回javascript / lodash

时间:2017-02-16 18:30:38

标签: javascript node.js lodash javascript-objects

我有2个深层嵌套的对象对象。一个是“基础”对象,另一个是修改过的对象。

我基本上想要从修改后的对象中“删除”基础对象,并返回仅包含不同数据的对象。这是一个例子:

基础对象:

baseObj : {
    image: {
        width: '100%',
        paddingTop: '0px',
        paddingRight: '0px',
        paddingBottom: '0px',
        paddingLeft: '0px'
    },
    wrap: {
        marginTop: '0px',
        marginRight: '0px',
        marginBottom: '0px',
        marginLeft: '0px'
    }
}

具有修改数据的对象

mergedObject : {
    image: {
        width: '100%',  
        paddingTop: '0px',
        paddingRight: '24px', // modified value
        paddingBottom: '24px', // modified value
        paddingLeft: '0px'
    },
    wrap: {
        height: '100px', // new value
        marginTop: '24px', // modified value
        marginRight: '0px',
        marginBottom: '0px',
        marginLeft: '24px' // modified value
    }
}

我想要一个像这样返回的对象:

diffObject : {
    image: {
        paddingRight: '24px',
        paddingBottom: '24px',
    },
    wrap: {
        height: '100px',
        marginTop: '24px',
        marginLeft: '24px'
    }
}

嵌套可能会更深一些,所以它需要是动态的。有没有办法使用lodash或其他一些库?

2 个答案:

答案 0 :(得分:2)

要解决这个问题,我们必须:

  • 创建一个以递归方式遍历对象中每个节点的函数。我们可以在遍历source对象时使用reduce函数来实现此目的。
  • reduce回调函数会首先检查source值或它的other值计数器部分是否都是对象。如果是,我们将使用这些值作为参数来递归地获取这两个对象的差异。否则,如果它们不同,那么我们将从other值中分配结果值。
  • 最后,reduce函数接受第三个参数,该参数用作reduce函数累计的初始值。我们使用other对象中未找到source对象中的键值来指定第三个参数。这是从other对象到结果对象的新引入值的最简单方法。
function differenceObjectDeep(source, other) {
  return _.reduce(source, function(result, value, key) {
    if (_.isObject(value) && _.isObject(other[key])) {
      result[key] = differenceObjectDeep(
        value,
        other[key]
      );
    } else if (!_.isEqual(value, other[key])) {
      result[key] = other[key];
    }
    return result;
  }, _.omit(other, _.keys(source)));
}

data.diffObject = differenceObjectDeep(
  data.baseObj,
  data.mergedObject
);



var data = {
  baseObj: {
    image: {
      width: '100%',
      paddingTop: '0px',
      paddingRight: '0px',
      paddingBottom: '0px',
      paddingLeft: '0px'
    },
    wrap: {
      marginTop: '0px',
      marginRight: '0px',
      marginBottom: '0px',
      marginLeft: '0px'
    }
  },
  mergedObject: {
    image: {
      width: '100%',
      paddingTop: '0px',
      paddingRight: '24px', // modified value
      paddingBottom: '24px', // modified value
      paddingLeft: '0px'
    },
    wrap: {
      height: '100px', // new value
      marginTop: '24px', // modified value
      marginRight: '0px',
      marginBottom: '0px',
      marginLeft: '24px' // modified value
    }
  }
};

function differenceObjectDeep(source, other) {
  return _.reduce(source, function(result, value, key) {
    if (_.isObject(value) && _.isObject(other[key])) {
      result[key] = differenceObjectDeep(
        value,
        other[key]
      );
    } else if (!_.isEqual(value, other[key])) {
      result[key] = other[key];
    }
    return result;
  }, _.omit(other, _.keys(source)));
}

data.diffObject = differenceObjectDeep(
  data.baseObj,
  data.mergedObject
);

console.log(data.diffObject);

body>div {
  min-height: 100%;
  top: 0;
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

您可以使用递归函数来查找最后一个对象。

    $newArray = [];

    for ($i = 0; $i < count($myArray); $i++)
    {
        $id_column = array_column($newArray, 'id');
        $qty_column = array_column($newArray, 'qty');
        if (!in_array($myArray[$i]['id'],$id_column)) {
            array_push($newArray, $myArray[$i]);
        }
        else {
            $id_pos = array_search($myArray[$i]['id'],$id_column);
            if ($myArray[$i]['qty'] < $qty_column[$id_pos])
            {
                array_splice($newArray,$id_pos,1,$myArray[$i]);
            }
        }
    }

您可以验证此jsfiddle link

的结果

注意:您需要根据reduce中的要求调整结果。此结果与您的输出相匹配。