【问题标题】:Can I use filter to extract values from an array of objects?我可以使用过滤器从对象数组中提取值吗?
【发布时间】:2020-11-01 18:29:22
【问题描述】:

我有一个对象数组:

const books = [
  {
    title: 'Book',
    author: 'Name'
  },
  {
    title: 'Book2',
    author: 'Name2'
  }
];

我想使用 filter 方法将标题提取到一个数组中。到目前为止,我尝试了这个,但数组返回了 2 个原始对象:

const getTheTitles = function(array) {
   const filteredArray = array.filter(function(book) {
      return book.title;
   })
   return filteredArray;
}

我也试过了,但结果是一个空数组(不知道为什么):

const getTheTitles = function(array) {
   const filteredArray = array.filter(function(book) {
      book.title;
   })
   return filteredArray;
}

我知道这可以使用 map 来完成。但我正在尝试使用过滤器来完成它。

【问题讨论】:

  • 你需要的是map,而不是filterconst titles = books.map(book => book.title);filter 用于 FILTER 不用于映射
  • developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… 您可以在此处阅读有关过滤器方法的信息,它显然不能满足您的要求
  • 谢谢。如前所述,我知道能够使用地图。有没有办法使用过滤器来做到这一点?还是因为我无法指定过滤条件而不可能?
  • 使用过滤器只能决定数组的哪一项应该在过滤后的数组中,但不能更改该项。

标签: javascript arrays filter


【解决方案1】:

如果您想获取某些过滤书籍的标题,则可以通过将map 链接到filter 来实现,如下所示:

let filteredBookTitles = books
  .filter(book => book.author === "Some Name")           // first filter (us any criteria here to select only the books you want)
  .map(book => book.title);                              // then get the titles of those filtered books

演示:

const books = [{ title: "Animal Farm", author: "George Orwell" }, { title: "Oliver Twist", author: "Charles Dickens" }, { title: "1984", author: "George Orwell" }];

let georgeOrwellBooks = books.filter(book => book.author === "George Orwell")
  .map(book => book.title);

console.log(georgeOrwellBooks);

或者通过使用reduce 来执行这两项操作,同时只循环一次数组,如下所示:

let filteredBookTitles = books.reduce((acc, book) => {   // for each book in the books array
  if(book.author === "Some Name") {                      // if the book matches the criteria
    acc.push(book.title);                                // add its title to the results array
  }

  return acc;
}, []);

演示:

const books = [{ title: "Animal Farm", author: "George Orwell" }, { title: "Oliver Twist", author: "Charles Dickens" }, { title: "1984", author: "George Orwell" }];

let georgeOrwellBooks = books.reduce((acc, book) => {
  if(book.author === "George Orwell") {
    acc.push(book.title);
  }

  return acc;
}, []);

console.log(georgeOrwellBooks);

【讨论】:

    【解决方案2】:

    您只能使用Array#filter 删除项目,但不能转换它们。过滤器功能应用于每个项目。如果函数返回true(或任何真实),则保留该项目,否则将其删除。

    示例:只保留奇数:

    [1,2,3,4,5].filter(n => n % 2 !== 0);
    //=> [1,3,5]
    

    示例:从布尔数组中删除 false

    [true,false,true,false].filter(b => b);
    //=> [true,true]
    

    您要做的是转换所有项目。例如从[{n:1},{n:2},{n:3}][1,2,3]。在这种情况下,您需要 Array#map 将函数应用于所有项目并使用结果创建一个新数组:

    [{n:1},{n:2},{n:3}].map(o => o.n);
    //=> [1,2,3]
    

    为什么这个函数会返回所有本书?

    const getTheTitles = function(array) {
      const filteredArray = array.filter(function(book) {
        return book.title;
      })
      return filteredArray;
    }
    

    问题是您的过滤器函数评估book.title 以决定是否保留图书对象。然而你所有的书都有一个标题,因此这个功能和说“这本书有标题吗?”是一样的

    为什么这个函数根本不返回书籍?

    const getTheTitles = function(array) {
      const filteredArray = array.filter(function(book) {
        book.title;
      })
      return filteredArray;
    }
    

    问题在于您的过滤器函数实际上并没有明确地返回任何内容。当一个函数没有return 语句时,它默认返回undefined,这是一个“假”值。这个功能和说“忽略所有的书”是一样的

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-15
      • 1970-01-01
      • 2014-06-30
      • 1970-01-01
      • 2014-03-06
      • 1970-01-01
      • 2018-12-31
      • 2020-02-14
      相关资源
      最近更新 更多