2013-08-05 3 views
1

Так что, кажется, я несколько раз царапаю голову над этим в течение последних нескольких часов .. примерно около 6 часов, и я просто не могу понять, как это понять. Я посмотрел на различные вопросы/ответы на SO, но никто из них не дал мне ответа.Ошибка рекурсивного сравнения объектов Javascript

Позвольте мне начать с объяснения того, что этот кусок кода SUPPOSE делать. Этот код будет соответствовать свойствам объекта с другим объектом, если он совпадает со всем объектом object_layout.


Примечание: Я хочу, чтобы объекты соответствовали, даже если полный object_layout, если не указан.

Объект данных:

var data = { 
    "some object" : { 
     name: "some object", 
     has: "properties", 
     types: [ 
      "some", 
      "type", 
      "of", 
      "array" 
     ] 
    }, 

    "another": { 
     property: false, 
     name: "another", 
     object: "here", 
     test: "this", 
     object: "strings" 
    }, 

    "minimal object": { 
     test: "this too" 
    }, 

    "minimal matching object": { 
     property: true, 
     name: "minimal matching object", 
     test: "this", 
     object: "strings" 
    }, 

    "matching object": { 
     test: "this", 
     property: true, 
     name: "matching object", 
     this_object: { 
      some: "object" 
    } 
    } 
}; 



Функция Прототип TypeOf, который может обнаружить массивы. Будет использоваться позже.

Object.prototype.typeof = function(object) { 
    if (!object) { return 'undefined' } 

    if (typeof(object) === "object" && 'splice' in object && 'join' in object) { 
     return 'array'; 
    } 

    return typeof(object); 
} 



Функция находкой, которая является прототипом объекта.

Object.prototype.find = function(object_layout) { 

    var found_objects; 

    for (object in this) { // loop through objects in this object. 

    if (object != 'typeof' && object != 'find') { // skip these functions in our object. 
     console.log('object: ' + object); 

     for (property in object_layout) { 

     if (object_layout.hasOwnProperty(property)) { 

      var object_type = Object.typeof(object_layout[property]); 
      if (object_type == 'string') { 

      console.log('Property ' + property); 
      console.log('value: ' + object_layout[property]); 

      if (object_layout[property] != this[object][property]) { // if object_layout property doesnt exist in object. 
      if (found_objects && found_objects[object]) { console.log(object + " removed from found_objects"); delete found_objects[object]; }// if in found_objects then remove. 
       console.log("property doesn't exist."); 
       break; // break to next object. 
      } 

      if (!found_objects) { found_objects = {} } 
      if (!found_objects[object]) { console.log("Added object: " + object); found_objects[object] = this[object]; } 

      } else if (object_type == 'object') { // recurse into object 
      console.log('object type: ' + property); 
      console.log("Recurse: " + JSON.stringify(this[object][property])); 

      if (this[object][property]) { 
       this[object][property].find(object_layout[property]); // recurse broken... 
      } 

      break; // break to next object 
      } 

     } 
     } 
    } 
    } 

    if (found_objects) { return found_objects; } 
    return false; 
} 



Вызов функции:

var results = data.find(
{ 
    test: "this", 
    property: true, 
    this_object: { 
    some: "object" 
    } 
}; 

console.log(results), true, 3)); 



Выход журнала (обрезаны последний бит)

Added object: matching object 
Property property 
value: true 
object type: this_object 
Recurse: {"some":"object"} 
object: some 
Property some 
value: object 
property doesn't exist. 



Все, кажется, работает до момента, когда оно повторяется, тогда как-то сравнение объектов становится все испорченным, и оно больше не подходит.

ответ

0

Ну, еще через несколько часов мне удалось заставить его работать, и я должен сказать, что я очень доволен результатами. На данный момент это:

  • добавляет прототип каждому объекту, чтобы вы могли его использовать в любом месте. Просто требуйте() его один раз в своем приложении.
  • будет искусно пропустить любые объекты, которые он не знает, как обращаться.
  • работает со строками, числами, булями и рекурсирует объекты для поиска совпадений.
  • recurses бесконечно на столько уровней, сколько вам нужно!

Я планирую добавлять объекты массива к списку, когда получаю еще некоторое время. На данный момент вот код. Я также планирую сделать это модулем для npm для пользователей Node. Возможно, даже загрузите его в Github. Будьте на связи.

Object.prototype.find = function(object_layout) { 

    var found_objects; 

    for (object in this) { // loop through objects in this object. 
     var this_object = object; // place to store the current object. 

     if (Object.typeof([this[object]]) != 'function') { 

      for (property in object_layout) { 
       var this_property = property; // place to store the current property; 

       if (Object.typeof(this[this_object][this_property]) != 'function') { 

        if (object_layout.hasOwnProperty(this_property)) { 

         var object_type = Object.typeof(object_layout[this_property]); 
         if (object_type == 'string' || object_type == 'number' || object_type == 'boolean') { 

          if (object_layout[this_property] != this[this_object][this_property]) { // if object_layout property doesnt exist in object. 
           if (found_objects && found_objects[this_object]) { delete found_objects[this_object]; }// if in found_objects then remove. 
           break; // break to next object. 
          } 

          // Add object to found_objects 
          if (!found_objects) { found_objects = {} } 
          if (!found_objects[this_object]) { found_objects[this_object] = this[this_object]; } 

         } else if (object_type == 'object') { // recurse into object 

          if (!this[this_object][this_property]) { //object property doesn't exist 
           if (found_objects && found_objects[this_object]) { delete found_objects[this_object]; }// if in found_objects then remove. 
           break; 
          } 

          var recurse_object_data = {} 
          recurse_object_data[this_property] = this[this_object][this_property]; 

          if (!recurse_object_data.find(object_layout[this_property])) { // recursive property doesn't exist, delete it. 
           if (found_objects && found_objects[this_object]) { delete found_objects[this_object]; }// if in found_objects then remove. 
           break; // break to next object. 

          } else { 
           // Add object to found_objects 
           if (!found_objects) { found_objects = {} } 
           if (!found_objects[this_object]) { found_objects[this_object] = this[this_object]; } 
          } 

         } else if (object_type == 'array') { 


         } else { 
          //console.log('.find object: ' + object_type); 
         } 
        } 

       } 
      } 
     } 
    } 

    if (found_objects && found_objects.size() > 0) { return found_objects; } 
    return false; 
} 
Смежные вопросы