【问题标题】:comparing two JavaScript objects比较两个 JavaScript 对象
【发布时间】:2013-07-02 22:28:34
【问题描述】:

所以,假设我有对象A 和对象B。对象 A 具有多个子对象,而对象 B 具有多个相同的子对象。如何找出对象B中缺少的和对象A中添加的有什么区别,然后将它们放入自己的对象或二维数组中。

例如,第一个数组是那些被添加到第二个的数组,被减去:

var changes = [["google.com", "yahoo.com"],["facebook.com", "bing.com"]]

我正在尝试使用 crossrider 比较存储书签的快照和当前书签列表。

【问题讨论】:

  • 您必须迭代并比较每个键/值对的字符串值(或其他值)等。要获得一些帮助,您必须发布应该与每个键/值对进行比较的对象其他,而不仅仅是您想要的数组。

标签: javascript jquery crossrider


【解决方案1】:

我相信这是以下问题的后续,因此我会将它们全部组合成一个在后台范围内运行的代码示例 (background.js): realtime with non-event programming, crossrider: store snapshot of bookmarks in local database and compare to current bookmarks list

所以对于 getChanges 函数,我更喜欢将书签树转换为哈希列表,然后比较列表的变化。在以下示例中,我使用 createHash 创建哈希列表,使用 cloneNode 创建节点对象的浅层克隆,然后在 getChanges我比较哈希列表的添加、修改和删除:

appAPI.ready(function() {
  // Poll every 30 seconds
  setInterval(function() {
    appAPI.db.async.get('prevBookmarks', function(value) {
      // Load or initialize the previous bookmarks list
      var prevBookmarks = (value) ? value : {};

      // Get current bookmarks
      appAPI.bookmarks.getTree(function(nodes) {
        // Save bookmark hash for comparison in next interval
        appAPI.db.async.set('prevBookmarks', createHash(nodes[0]));

        // Get hash list of curent bookmarks
        var currBookmarks = createHash(nodes[0]);

        // Get changes between the lists
        var changes = getChanges(prevBookmarks, currBookmarks);

        // Post changes to your API server
        appAPI.request.post({
          url: http://yourAPIserver.com,
          postData: changes,
          contentType: 'application/json'
        });
      });
    });
  }, 30 * 1000);

  // Function to create a hash list from a bookmark tree
  function createHash(node) {
    var hash = {};
    if (typeof node === 'object') hash[node._id] = cloneNode(node);

    if (node.isFolder && typeof node.children !== 'undefined' && node.children.length > 0)  {
      node.children.forEach(function(child) {
        var childHash = createHash(child);
        for (var key in childHash) {
          if (!hash[key]) hash[key] = cloneNode(childHash[key]);
        }
      });
    }
    return hash;
  }

  // Function to create shallow clones of bookmark nodes
  function cloneNode(node) {
    var clone = appAPI.JSON.parse(appAPI.JSON.stringify(node));
    delete clone.children;
    delete clone.dateAdded;
    return clone;
  }

  // Get changes between current and previous bookmark hash lists
  function getChanges(prev, curr) {
      // Initialize return object
      var changes = {added:{}, modified:{}, removed:{}};

      // Search for added or modified nodes
      for (var key in curr) {
          if (!prev[key])
            changes.added[key] = curr[key];
          else if (appAPI.JSON.stringify(prev[key]) !== appAPI.JSON.stringify(curr[key]))
            changes.modified[key] = curr[key];
      }

      // Search for removed nodes
      for (var key in prev) {
          if (!curr[key])
            changes.removed[key] = prev[key];
      }
      return changes;
  }
});

免责声明:我是 Crossrider 的员工

【讨论】:

    【解决方案2】:

    如果要比较的两个对象都是一维数组,那么只需使用Underscore.js中设置的算术函数即可,如_.difference_.intersection

    或者,使用相同的逻辑,相交(未优化)很简单:

    array1.filter(function(v){return array2.indexOf(v)!==-1);});
    

    如果您正在寻找一种通用方法来查找任意深度和复杂度的两个任意对象之间的差异,那么这不是一个明确定义的问题。

    【讨论】:

      猜你喜欢
      • 2019-08-02
      • 2020-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多