【问题标题】:Accessing object value inside array using forEach? [duplicate]使用forEach访问数组内的对象值? [复制]
【发布时间】:2019-02-12 23:55:58
【问题描述】:

您好,这是我的第一个问题。我有一个看起来像这样的对象数组:

    const albums = [{title: 'title1', id: 1}, {title: 'title2', id: 2}, 
{title: 'title3', id: 3}]

我想从这个数组中通过 id 提取 title 的动态值。这意味着如果我在此运行一个函数,我想在 id 指定为“1”时接收“t​​itle1”。我尝试了很多方法,包括现在看起来像这样的 forEach 循环:

albums.forEach(function(key, index, arr) {
        arr[index].title })

我在本网站的其他地方读到,for/forEach 循环可用于从对象数组中的对象中提取值。但我想我并不完全理解 forEach 循环在这方面是如何工作的,因为我无法从中提取任何价值。如果在 forEach 循环中我调用一个 console.log (就像console.log(arr[index].title) 它很好地记录了数组中每个元素的 title 属性的值。但是当我尝试返回(return arr[index].title)并调用它来的函数时向上为未定义。

总之我有这两个问题:

  1. 在对象数组中访问对象中的值的最佳方法是什么?

  2. 在尝试访问对象数组中的对象时,forEach 循环是如何工作的?

感谢您的任何意见、建议和反馈

【问题讨论】:

标签: javascript arrays nested javascript-objects


【解决方案1】:

JavaScript 有多种方法可以提取和操作数组中的对象。以下是与您的问题相关的一些最常见的问题:

const albums = [{title: 'title1', id: 1}, {title: 'title2', id: 2}, 
{title: 'title3', id: 3}];

// For each is for doing something that causes side effects
albums.forEach(({title}) => console.log(title))
// nothing is returned
// console output:
// title1
// title2
// title3

// Map is for transforming each object in the array into something else
const titles = albums.map(({title}) => title);
// => ['title1', 'title2', title3']

// If you need to find a specific one, use find
const albumWithId3 = albums.find(({id}) => id === 3);
// => {title: 'title3', id: 3}

// If you need to find a subset, use filter
const ablumsWithIdsLessThan3 = albums.filter(({id}) => id < 3)
// => [{title: 'title1', id: 1}, {title: 'title2', id:2}]

要直接回答您的问题,您可能需要这样的内容:

const albums = [{title: 'title1', id: 1}, {title: 'title2', id: 2}, 
{title: 'title3', id: 3}];

const getTitle = album => album ? album.title : undefined;
const idToAlbum = (myId, albums) => albums.find(({id}) => myId === id);
const idToTitle = (myId, albums) => getTitle(idToAlbum(myId, albums));

const title = idToTitle(1, albums);
console.log(title);
// => 'title1'

或者,如果您更喜欢命令式风格:

const albums = [{title: 'title1', id: 1}, {title: 'title2', id: 2}, 
{title: 'title3', id: 3}];

const idToTitle = (id, albums) => {
  for (const album of albums) {
    if (album.id === id) {
      return album.title;
    }
  }
}

const title = idToTitle(1, albums);
console.log(title);
// => 'title1'

【讨论】:

    【解决方案2】:

    (1) 要在数组中查找值,Array.prototype.find 几乎总是您的最佳选择。

    const albums = [{title: 'title1', id: 1}, {title: 'title2', id: 2}, {title: 'title3', id: 3}]
    
    const findAlbum = (id) => albums.find(album => album.id === id)
    
    console.log(findAlbum(2)); //~> {title: 'title2', id: 2}

    (2) forEach 可以工作,但它通常不是最适合这项工作。 forEach 是关于针对元素运行函数。它本质上并不捕获结果。所以你可以像这样包装它:

    const albums = [{title: 'title1', id: 1}, {title: 'title2', id: 2}, {title: 'title3', id: 3}]
    
    const findAlbum = (id) => {
      let found 
      albums.forEach(album => {
        if (!found && album.id === id) {
          found = album
        }
      })
      return found
    }
    
    console.log(findAlbum(2)) //~> {title: 'title2', id: 2}

    该代码显然更复杂。它掩盖了一个事实,即你想做的是“找到”一些东西。

    (它还有一个更隐蔽的问题。如果您想在可能为 false-y 值的列表中查找某些内容,它会继续搜索该值是否为 false-y。因此,如果您要更改它以尝试在[3, 5, 7, 0, 11, 14, 13, 17, 20] 中找到第一个偶数,它会跳过 false-y 0 并返回 14。)您可以通过将 found 拆分为两个变量来解决此问题,一个用于检查我们是否找到任何东西,然后另一个来存储找到的值,但这会使代码更加复杂,尤其是当我们有一个可用的find 方法时。)

    (3) 你可以把它分解成一些可重用的助手。我不会在这里写它们。但是您可以编写通用的可重用 whereequals 函数,使代码看起来更像这样:

    const findAlbum = (id) => albums.find(where('id', equals(id)))
    

    这对我来说更具可读性。

    【讨论】:

      【解决方案3】:

      您可以使用Array#find() 来查找符合您想要的任何条件的数组元素。

      如果有匹配,则从该元素返回您想要的任何内容

      const albums = [{title: 'title1', id: 1}, {title: 'title2', id: 2},
      {title: 'title3', id: 3}]
      
      
      const getTitleById = (id) => {
        const o = albums.find(album => album.id === id);
        return o && o.title
      }
      
      
      console.log(getTitleById(2))
      console.log(getTitleById(3))

      【讨论】:

        【解决方案4】:

        试试这个代码:

        const albums = [{ title: 'title1',id: 1}, {title: 'title2',id: 2},{title: 'title3',id: 3}]
        
        var idToFind = 2;
        albums.forEach((element) => {
          if (element.id == idToFind) {
            console.log(element.title)
          }
        })

        【讨论】:

          【解决方案5】:

          为了保持一致性,您应该使用 forEach 作用域,如下所示:

          var Album = function(arr){
              this.arr = arr;
              this.get = function(id){
                  this.arr.forEach((element) => {
                      if (element.id == id) {
                          console.log(element.title)
                      }
                  })
              }
          }
          
          a = new Album([{title: 'title1', id: 2}]);
          a.get(2)
          

          这应该返回'title1'

          【讨论】:

            【解决方案6】:
            1. 如果您知道对象在数组中的位置,只需使用位置访问它。即console.log(albums[4].title)。但是,如果您不知道您需要遍历每个位置并搜索相关对象的位置。那么最好的方法是编写一个返回对象的搜索函数。

            const albums = [{title: 'title1', id: 1}, {title: 'title2', id: 2}, 
            {title: 'title3', id: 3}];
            
            console.log(serachArrayByTitle(albums,'title2'));
            
            function serachArrayByTitle(arrayToSerach,titleToSearchFor){
              for(var i=0;i<arrayToSerach.length;i++){
                if(arrayToSerach[i].title===titleToSearchFor){
                  return arrayToSerach[i];
                }
              }
            }
            1. forEach() 为数组的每个元素执行给定的回调函数。在这里阅读更多:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach

            【讨论】:

              【解决方案7】:

              试试这个:

              function getTitleById(id) 
                  {
                  var i;
                  for (i = 0; i < albums.length; i++) { 
                      if(albums[i]['id'] == id)
                      return albums[i]['title'];
                  }
                  }
              

              【讨论】:

                猜你喜欢
                • 2020-09-19
                • 1970-01-01
                • 1970-01-01
                • 2013-12-29
                • 2013-04-28
                • 2021-12-16
                • 2015-05-04
                • 2020-07-11
                • 2012-02-27
                相关资源
                最近更新 更多