Рекурсивная функция неправильно оценивает ключи в объектах

#javascript #vue.js

#javascript #vue.js

Вопрос:

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

Вот originalReference :

 {  
   "id":68,
   "article_id":12338,
   "article_reference_id":68,
   "article_reference_extraction_id":667320,
   "user_id":null,
   "file":"1238-230180-1-CE.doc",
   "revision":1,
   "order":1,
   "type":"journal",
   "preview":"Chewning B, Bylund CL, Shah B, Arora NK, Gueguen JA, Makoul G. Patient preferences for shared decisions: a systematic review. Patient Educ Couns 2012 Jan; 86(1):9-18",
   "status":1,
   "source":"Unknown",
   "data":{  
      "pii":"S0738-3991(11)00114-5",
      "webciteId":null,
      "publication":[  

      ],
      "conference":[  

      ],
      "authors":[  
         {  
            "firstName":"B",
            "lastName":"Chewning"
         },
         {  
            "firstName":"CL",
            "lastName":"Bylund"
         },
         {  
            "firstName":"B",
            "lastName":"Shah"
         },
         {  
            "firstName":"NK",
            "lastName":"Arora"
         },
         {  
            "firstName":"JA",
            "lastName":"Gueguen"
         },
         {  
            "firstName":"G",
            "lastName":"Makoul"
         }
      ],
      "editors":[  
         {  
            "firstName":"G",
            "lastName":"Makoul"
         }
      ],
      "comments":[  

      ],
      "source":{  
         "title":"Patient Educ Couns",
         "date":{  
            "year":"2012",
            "month":"01",
            "day":null
         },
         "pages":{  
            "from":"9",
            "to":"18"
         },
         "volume":"86",
         "issue":"1",
         "url":"http://europepmc.org/abstract/MED/21474265"
      },
      "accessDate":null,
      "articleTitle":"Patient preferences for shared decisions: a systematic review"
   },
   "doi":"10.1016/j.pec.2011.02.004",
   "pmid":21474265,
   "pmcid":null,
   "isbn":"",
   "created_at":"2019-04-09 10:04:53",
   "updated_at":"2019-04-09 10:04:53",
   "deleted_at":null,
   "max_revision":30,
   "extraction":{  
      "id":667320,
      "article_id":12338,
      "file":"1238-230180-1-CE.doc",
      "order":1,
      "original":"Chewning B, Bylund CL, Shah B, Arora NK, Gueguen JA, Makoul G. Patient preferences for shared decisions: A systematic review. Patient Educ Couns [Internet] Elsevier Ireland Ltd; 2012;86(1):9?18. PMID:21474265",
      "doi":null,
      "pmid":null,
      "isbn":null,
      "parsed":1,
      "created_at":"2019-02-25 18:40:46",
      "updated_at":"2019-02-25 18:40:46",
      "deleted_at":null
   }
}
  

И вот reference :

 {  
   "id":68,
   "article_id":12338,
   "article_reference_id":68,
   "article_reference_extraction_id":667320,
   "user_id":null,
   "file":"1238-230180-1-CE.doc",
   "revision":1,
   "order":1,
   "type":"journal",
   "preview":"Chewning B, Bylund CL, Shah B, Arora NK, Gueguen JA, Makoul G. Patient preferences for shared decisions: a systematic review. Patient Educ Couns 2012 Jan; 86(1):9-18",
   "status":1,
   "source":"Unknown",
   "data":{  
      "pii":" ",
      "webciteId":null,
      "publication":[  

      ],
      "conference":[  

      ],
      "authors":[  
         {  
            "lastName":"Chewning",
            "firstName":"Betty"
         },
         {  
            "lastName":"Bylund",
            "firstName":"Carma L."
         },
         {  
            "lastName":"Shah",
            "firstName":"Bupendra"
         },
         {  
            "lastName":"Arora",
            "firstName":"Neeraj K."
         },
         {  
            "lastName":"Gueguen",
            "firstName":"Jennifer A."
         },
         {  
            "lastName":null,
            "firstName":" "
         }
      ],
      "editors":[  
         {  
            "firstName":"G",
            "lastName":"Makoul"
         }
      ],
      "comments":[  

      ],
      "source":{  
         "title":"Patient Education and Counseling",
         "date":{  
            "year":2012,
            "month":1,
            "day":null
         },
         "pages":{  
            "from":"9",
            "to":"18"
         },
         "volume":"86",
         "issue":"1",
         "url":"http://europepmc.org/abstract/MED/21474265"
      },
      "accessDate":null,
      "articleTitle":"Patient preferences for shared decisions: A systematic review"
   },
   "doi":"10.1016/j.pec.2011.02.004",
   "pmid":21474265,
   "pmcid":null,
   "isbn":"",
   "created_at":"2019-04-09 10:04:53",
   "updated_at":"2019-04-09 10:04:53",
   "deleted_at":null,
   "max_revision":30,
   "extraction":{  
      "id":667320,
      "article_id":12338,
      "file":"1238-230180-1-CE.doc",
      "order":1,
      "original":"Chewning B, Bylund CL, Shah B, Arora NK, Gueguen JA, Makoul G. Patient preferences for shared decisions: A systematic review. Patient Educ Couns [Internet] Elsevier Ireland Ltd; 2012;86(1):9?18. PMID:21474265",
      "doi":null,
      "pmid":null,
      "isbn":null,
      "parsed":1,
      "created_at":"2019-02-25 18:40:46",
      "updated_at":"2019-02-25 18:40:46",
      "deleted_at":null
   }
}
  

Обратите внимание, что articleTitle in originalReference имеет опечатки, но articleTitle in reference имеет правильный заголовок.

Смысл приведенной ниже функции заключается в том, чтобы гарантировать, что если originalReference ранее для ключа было непустое / ненулевое / определенное значение, reference не следует перезаписывать значение originalReference .

И вот функция, которая оценивает оба.

Происходит то, что она выдает ошибку TypeError: Cannot read property 'articleTitle' of undefined , когда они оба четко определены. Не уверен, что происходит.

Вот функция:

 evaluateEmptyValues: function(reference, originalReference) {
    var vm = this;

    console.log('reference', reference);
    console.log('Before   --> '   reference.data.articleTitle);

    // Get keys and values of both reference objects
    referenceLength = Object.entries(reference).length;
    originalReferenceLength = Object.entries(originalReference).length;

    if (referenceLength == originalReferenceLength) {
        try {
            for (var prop in reference) {
                    if (reference[prop] != undefined || reference[prop] != null) {
                        if (typeof (reference[prop]) == 'string' amp;amp; reference[prop].trim() == '') {
                            reference[prop] = originalReference[prop];
                        }

                        if (typeof(reference[prop]) == 'object' amp;amp; typeof(originalReference[prop]) == 'object') {
                            console.log('reference[prop]', reference[prop]);
                            console.log('originalReference[prop]', originalReference);
                            vm.evaluateEmptyValues(reference[prop], originalReference[prop]);
                        }

                        if (Array.isArray(reference[prop]) amp;amp; typeof Array.isArray(originalReference[prop])) {
                            reference[prop].forEach((item, index) => vm.evaluateEmptyValues(item, originalReference[prop][index]));
                        }
                } else {
                    reference[prop] = originalReference[prop];
                }
            }
        } catch(err) {
            console.log(err);
        }
    }

    console.log('After    --> '   reference.data.articleTitle);
    //
    // console.log('Original --> '   originalReference.data.articleTitle);
}
  

Комментарии:

1. что вы хотите получить в итоге?

2. вы пытаетесь выполнить рекурсивное слияние? потому что есть _.merge и _.mergeWith

Ответ №1:

Не должна ли ваша строка

 if (reference[prop] != undefined || reference[prop] != null) {
  

использовать И, как это?

 if (reference[prop] != undefined amp;amp; reference[prop] != null) {
  

Комментарии:

1. Нет, потому что, если любой из них имеет значение true, я хочу, чтобы он попал в else . Возможно reference[prop] == null , или reference[prop] == undefined .. но originalReference[prop] может и не быть, поэтому я хочу назначить reference[prop] = originalReference[prop]; . И если originalReference[prop] == null || originalReference[prop] == undefined , то это тоже нормально — ничего не изменилось

Ответ №2:

Получил работу с этим:

 evaluateEmptyValues: function(reference, originalReference) {
    var vm = this;

    // Get keys and values of both reference objects
    referenceLength = Object.entries(reference).length;
    originalReferenceLength = Object.entries(originalReference).length;

    if (referenceLength == originalReferenceLength) {
        try {
            for (var prop in reference) {
                if (reference[prop] != undefined || reference[prop] != null) {
                    if (typeof (reference[prop]) == 'string' amp;amp; reference[prop].trim() == '') {
                        reference[prop] = originalReference[prop];
                    }

                    if (typeof(reference[prop]) == 'object' amp;amp; typeof(originalReference[prop]) == 'object') {

                        var length = Object.keys(reference[prop]).length;
                        for (var property in reference[prop]) {
                            if (originalReference[prop][property] != undefined) {
                                if (originalReference[prop][property] != null) {
                                    // vm.evaluateEmptyValues(reference[prop][property], originalReference[prop][property]);
                                    for (var i = 0; i < property.length; i  ) {
                                        if ((reference[prop][property] == null || reference[prop][property] == '') amp;amp;
                                            originalReference[prop][property] != null) {
                                            reference[prop][property] = originalReference[prop][property];
                                        }
                                    }
                                }
                            }
                        }
                    }

                    if (Array.isArray(reference[prop]) amp;amp; typeof Array.isArray(originalReference[prop])) {
                        reference[prop].forEach((item, index) => vm.evaluateEmptyValues(item, originalReference[prop][index]));
                    }
                } else {
                    if (originalReference[prop] != undefined) {
                        if (originalReference[prop] != null) {
                            reference[prop] = originalReference[prop];
                        }
                    }
                }
            }
        } catch(err) {
            console.log(err);
        }
    }
},