функция с .filter (), возвращающая неопределенное значение вместо отфильтрованного массива - PullRequest
4 голосов
/ 29 июня 2019

Я пытаюсь понять метод javascript Array.filter.

Почему следующий код возвращает undefined? Чего мне не хватает?

function driversWithRevenueOver(driver, revenue) {
  driver.filter(function(person) {
    if (person.revenue >= revenue) {
      return person;
    }
  });
}

  driversWithRevenueOver(
    [
      { name: "Sally", revenue: 400 },
      { name: "Annette", revenue: 200 },
      { name: "Jim", revenue: 150 },
      { name: "Sally", revenue: 200 }
    ],
    250
  );

Возвращается:

[{ name: 'Sally', revenue: 400 }]

Ответы [ 5 ]

5 голосов
/ 29 июня 2019

Согласно документации по Array.filter :

Метод filter () создает новый массив со всеми проходящими элементами тест реализован с помощью предоставленной функции.

Итак, в вашем случае главная проблема заключается в том, что ваша функция does not return anything, даже если вы вызвали Array.filter. Так что вам нужно:

function driversWithRevenueOver(driver, revenue) {
  return driver.filter(function(person) {  // <-- return here
    return person.revenue >= revenue)
  });
}

Дополнительная информация о функции, которую вы передаете в Array.filter, также известный как callback :

Функция является предикатом, чтобы проверить каждый элемент массива. Вернуть true для сохранения элемента, false в противном случае.

Так что вам нужно вернуть boolean value из функции.

Более короткая версия этого фильтра может быть просто:

let data = [{ name: "Sally", revenue: 400 }, { name: "Annette", revenue: 200 }, { name: "Jim", revenue: 150 }, { name: "Sally", revenue: 200 } ]

let result = data.filter(x => x.revenue > 250)  // <-- function returns boolean

console.log(result)
3 голосов
/ 29 июня 2019

Вам необходимо вернуть результат filter() из функции. Также вы должны вернуть true или false из filter(), а не само значение.

function driversWithRevenueOver(driver, revenue) {
  return driver.filter(function(person) {
    return person.revenue >= revenue
  });
}

С функцией стрелки она будет выглядеть более чистой.

const driversWithRevenueOver = (driver, revenue) => 
    driver.filter(person => person.revenue >= revenue);
2 голосов
/ 29 июня 2019

Он возвращает неопределенное значение, потому что вы никогда не возвращаетесь к своей внешней функции:

function driversWithRevenueOver(driver, revenue) {...}

Пока вы выполняете return внутри этой функции, вы возвращаетесь к функции внутреннего обратного вызова, помещенной в .filter(<em>callback</em>):

driver.filter(function(person) { <---- 
  if (person.revenue >= revenue) {   | returns to callback (not driversWithRevenueOver)
    return person; ------------------|
  }
});

Таким образом, ваш driversWithRevenueOver неявно возвращает undefined (поскольку вы не вызываете, возвращая что-либо внутри него). Итак, вам нужно вернуть результат .filter(). Кроме того, вам также необходимо исправить ваше заявление return. Метод filter сохранит элементы в исходном массиве driver, если вы вернете true, и удалите его, если вы вернете false изнутри внутреннего обратного вызова. Таким образом, вы можете просто вернуть оценку person.revenue >= revenue:

function driversWithRevenueOver(driver, revenue) {
  return driver.filter(function(person) {
    return person.revenue >= revenue;
  });
}

function driversWithRevenueOver(driver, revenue) {
  return driver.filter(function(person) {
    return person.revenue >= revenue;
  });
}

const res = driversWithRevenueOver(
  [{
      name: "Sally",
      revenue: 400
    },
    {
      name: "Annette",
      revenue: 200
    },
    {
      name: "Jim",
      revenue: 150
    },
    {
      name: "Sally",
      revenue: 200
    }
  ],
  250
);

console.log(res);
0 голосов
/ 29 июня 2019

Вам нужна только одна модификация в вашем коде, остальное хорошо.

function driversWithRevenueOver(driver, revenue) {
  return driver.filter(function(person) { // you forgot to return the filtered array
    if (person.revenue >= revenue) {
      return person;
    }
  });
}

driversWithRevenueOver(
    [
      { name: "Sally", revenue: 400 },
      { name: "Annette", revenue: 200 },
      { name: "Jim", revenue: 150 },
      { name: "Sally", revenue: 200 }
    ],
    250
);
0 голосов
/ 29 июня 2019

Вам нужно return отфильтрованный массив.

return driver.filter(...);

Вы также можете сделать свой код более лаконичным, например, - и заметьте, что filter просто нужен логический ответ.

const driversWithRevenueOver = (driver, revenue) =>  driver.filter(({ revenue: r }) => r >= revenue);

console.log(driversWithRevenueOver(
  [{name:"Sally",revenue:400},{name:"Annette",revenue:200},{name:"Jim",revenue:150},{name:"Sally",revenue:200}],
  250
));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...