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

Зачем нам нужно reduce сопоставленное логическое значение для одного значения в конце функции?

Цель функции - отфильтровать массив объектов (первый аргумент) с помощьюkey value пар из другого объекта (второй аргумент).

Он должен возвращать другой массив object с объектами из первого аргумента, который соответствует key и value извторой аргумент.

Например, если первый аргумент - [{ first: "Romeo", last: "Montague" }, { first: "Mercutio", last: null }, { first: "Tybalt", last: "Capulet" }]

, а второй - { last: "Capulet" }

Функция должна вернуть [{ first: "Tybalt", last: "Capulet" }]

Это решение, на которое я наткнулся и не могу понять, как здесь работают map() и reduce().

function whatIsInAName(collection, source) {
  var srcKeys = Object.keys(source);

  return collection.filter(function (obj) {
    return srcKeys
      .map(function(key) {
        return obj.hasOwnProperty(key) && obj[key] === source[key];
      })
      .reduce(function(a, b) {
        return a && b;
      });
  });
}

Спасибо!

Ответы [ 2 ]

0 голосов
/ 02 октября 2018

Давайте начнем с этой функции, которая используется в решении.Это предикат, который берет один из ключей от объекта в source и возвращает логическое значение:

function(key) {
    return obj.hasOwnProperty(key) && obj[key] === source[key];
}

Немного сложнее то, что он также ссылается на obj, что в контексте относится к одному изобъекты в collection.Таким образом, вы можете думать об этом, на данном этапе объяснения, как функцию двух переменных:

function(obj, key) {
    return obj.hasOwnProperty(key) && obj[key] === source[key];
}

Так когда же это правда?Это легко: когда obj имеет key в качестве одного из своих ключей и для которого значение равно значению source для того же ключа.Другими словами, он проверяет, согласны ли obj и source в отношении ключа key.

Так что же нам делать с этой функцией?Мы map это над массивом srcKeys - который содержит все ключи source.Итак, помня, что это со ссылкой на фиксированный объект obj, мы получаем массив логических значений, указывающих, найден ли каждый ключ source с тем же значением в obj.

Тогдаоперация reduce, которая просто использует оператор &&, просто проверяет, являются ли все значения в этом массиве логических значений истинными.Итак, мы видим, что этот раздел кода:

return srcKeys
  .map(function(key) {
    return obj.hasOwnProperty(key) && obj[key] === source[key];
  })
  .reduce(function(a, b) {
    return a && b;
  });

возвращает логическое значение, проверяющее, имеет ли obj все ключи, указанные в source, и соглашается со значениями.

Последнийшаг теперь является естественным - collection является filter ed этим предикатом, означая, что конечный результат - это массив, состоящий из тех элементов collection, которые согласуются с source во всех ключах source.Это именно то, что было желаемое поведение:)

0 голосов
/ 02 октября 2018

Сначала функция создает массив всех ключей, которые нужно искать в srcKeys, например, ['last'].Для правильной иллюстрации этого алгоритма предположим, что вы ищете два ключа: source = { last: 'Capulet', first: 'Jon' }['last', 'first'].

Затем он отображает этот массив в массив логических значений, где каждое значение указывает, является лиЭлемент в collection имеет этот ключ, и его значение такое же, как в source.Например:

['last', 'first'] → [true, true]    // or
['last', 'first'] → [false, false]  // or
['last', 'first'] → [false, true]   // ...

Затем этот массив логических значений сводится к одному логическому результату, который будет равен true, если все элементы в массиве равны true:

[true, true]   → true
[false, false] → false
[false, true]  → false
* 1016.*

FWIW, вы можете сделать это за один шаг, используя Array.prototype.every:

return collection.filter(obj => {
  return srcKeys.every(key => obj.hasOwnProperty(key) && obj[key] === source[key]);
});
...