сравнение двух объектов JavaScript

Итак, допустим, у меня есть объект A и объект B. У объекта A есть несколько дочерних элементов, а у объекта B — несколько одинаковых дочерних элементов. Как узнать, в чем отличия отсутствующих в объекте B и добавленных в объект A, а затем поместить их в свой собственный объект или двумерный массив.

Например, первый массив — это те, которые добавляются ко второму, вычитаемому:

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

Я пытаюсь сравнить снимок сохраненных закладок и текущий список закладок с помощью crossrider.


person user2491588    schedule 02.07.2013    source источник
comment
Вы должны повторять и сравнивать строковые значения (или что-то еще) каждой пары ключ/значение и т. д. Чтобы получить некоторую помощь в этом, вам нужно будет опубликовать объекты, которые должны сравниваться друг с другом, а не только массив, который вы хотел бы закончить с.   -  person adeneo    schedule 03.07.2013


Ответы (2)


Я считаю, что это продолжение следующих вопросов, поэтому я объединим их все в один пример кода, который выполняется в фоновом режиме (background.js): в реальном времени с программированием без событий, crossrider: сохранять моментальные снимки закладок в локальной базе данных и сравнивать их с текущим списком закладок

Поэтому для функции 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

person Shlomo    schedule 03.07.2013

Если два сравниваемых объекта являются одномерными массивами, просто используйте арифметические функции set в Underscore.js, такие как _.difference и _.intersection.

Или используйте ту же логику, которая для пересечения (неоптимизированного) так же проста, как:

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

Если вы ищете общий способ найти разницу между двумя произвольными объектами любой глубины и сложности, это не является четко определенной проблемой.

person Community    schedule 03.07.2013