Отладка функции JavaScript - Почему эта функция фильтра не работает должным образом? - PullRequest
0 голосов
/ 30 апреля 2018

JavaScript - Скрипты для промежуточного алгоритма

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

Хотя правильное решение дано по адресу freeCodeCamp , я хотел бы знать, каковы проблемы и ошибки в моем коде. Кроме того, я нашел решение для переполнения стека, но я не понимаю, что не так с моим кодом.


Вот мой код

function whatIsInAName(collection, source) {
  // What's in a name?
  var arr = [];
  // Only change code below this line
  var obj;
  var prop;
  var keys = Object.keys(source);
  for (var i = 0; i < collection.length; i++) {
    for (var j = 0; j < Object.keys(source).length; j++) {
      obj = collection[i];
      prop = Object.keys(source)[j];
      if (obj.hasOwnProperty(prop) && obj.prop === source.prop) {
        arr = arr.concat([obj]);
      }
    }
  }
  // Only change code above this line
  return arr;
}

whatIsInAName([{ first: "Romeo", last: "Montague" }, { first: "Mercutio", last: null }, { first: "Tybalt", last: "Capulet" }], { last: "Capulet" });

Вот результат, который я получаю

[{ first: "Romeo", last: "Montague" }, { first: "Mercutio", last: null }, { first: "Tybalt", last: "Capulet" }]

Вместо

[{ first: "Tybalt", last: "Capulet" }]

Ответы [ 2 ]

0 голосов
/ 30 апреля 2018

[Кристианмитк, по-видимому, добавил какое-то объяснение в то время, когда я писал это, но я также оставлю этот ответ здесь, на случай, если альтернативное объяснение кому-нибудь пригодится ...]


То, что Кристианмитк говорит, правильно, но, возможно, могло бы использовать какое-то объяснение.

Причина, по которой ваш код возвращает каждый элемент, заключается в том, что в каждом случае вы проверяете

if (/*...*/ && obj.prop === source.prop) {
    //...
}

Но obj.prop означает «свойство с именем prop»; то есть вы бы использовали его, чтобы найти значение "xyzzy" объекта, объявленного как

{ prop: "xyzzy" }

Вам нужно проверить свойство, названное значением переменной prop . Это делается с помощью оператора [].

var prop = "foo";
var obj = { prop: "nope" , foo: "found it" };

// these are true:
obj.prop === "nope"
obj[prop] === "found it"

В вашем тестовом примере, поскольку ни один из рассматриваемых объектов не обладает свойством prop, все значения равны undefined. А поскольку JavaScript динамический, можно ссылаться на эти неопределенные значения (без ошибок). И поскольку JavaScript был написан язычниками, undefined === undefined - это true.

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

var keys = Object.keys(source);

вы позже несколько раз делаете дополнительные звонки на Object.keys(source), когда вы можете просто сказать keys. Это не так, как утверждают некоторые, вопрос о том, что является «эффективным». Когда-то использование переменной было определенно более эффективным, и, возможно, все-таки это так, но забота об оптимизации на этом уровне не является хорошей идеей. Забота о читабельности - хорошая идея, и как только вы дадите массиву keys красивое, простое имя (keys), вы должны его использовать.

0 голосов
/ 30 апреля 2018

В вашем , если заявлении вы должны иметь obj[prop] === source[prop] вместо obj.prop === source.prop. См. имена вычисленных свойств .

Поскольку оба объекта не содержат свойства prop, условие всегда оценивается как true (undefined === undefined равно true).


Демо

(обратите внимание, что я переместил obj = collection[i]; во внешний цикл, поскольку излишне назначать его каждый раз во внутреннем цикле)

function whatIsInAName(collection, source) {
  // What's in a name?
  var arr = [];
  // Only change code below this line
  var obj;
  var prop;
  var keys = Object.keys(source);
  for (var i = 0; i < collection.length; i++) {
    obj = collection[i];
    for (var j = 0; j < Object.keys(source).length; j++) {
      prop = Object.keys(source)[j];
      if (obj.hasOwnProperty(prop) && obj[prop] === source[prop]) {
        arr = arr.concat([obj]);
      }
    }
  }
  // Only change code above this line
  return arr;
}

let res = whatIsInAName([{ first: "Romeo", last: "Montague" }, { first: "Mercutio", last: null }, { first: "Tybalt", last: "Capulet" }], { last: "Capulet" });

console.log(res)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...