【问题标题】:Javascript Loops: for-loop works but not map?Javascript 循环:for 循环可以工作,但不能映射?
【发布时间】:2016-11-02 09:10:15
【问题描述】:

我正在为 web 应用程序使用 mockData,并且我正在尝试遍历嵌套对象。我的问题是 for 循环有效但不是 array.map 并且不知道为什么。

这是for循环:

  for (let i = 0; i < fakeChartData.length; i++) {
    for (let j = 0; j < fakeChartData[i].poll.length; j++) {
      if (fakeChartData[i].poll[j].id === id) {
        return fakeChartData[i].poll[j]
      }
    }
  }

这是地图循环:

  fakeChartData.map(data => {
    data.poll.map(data => {
      if (data.id === id) {
        return data;
      }
    });
  });

我的数据结构:

fakeChartData = [
  {
    id: '232fsd23rw3sdf23r',
    title: 'blabla',
    poll: [{}, {}]
  },
  {
    id: '23dgsdfg3433sdf23r',
    title: 'againBla',
    poll: [{}, {}]
  }
];

我正在尝试使用 onClick 方法传递给它的 id 加载特定对象。 这是完整的功能:

export const fetchPollOptById = (id) =>
  delay(500).then(() => {
    for (let i = 0; i < fakeChartData.length; i++) {
      for (let j = 0; j < fakeChartData[i].poll.length; j++) {
        if (fakeChartData[i].poll[j].id === id) {
          return fakeChartData[i].poll[j]
        }
      }
    }
});

【问题讨论】:

  • 你应该提供一个数据结构的例子......
  • 运行情况如何?我们在测试中使用 array.map 时遇到问题。它们使用 jasmine 和 phantom.js 运行。 Phantom.js 似乎缺少对 array.map 的支持
  • 考虑map 中的return 语句从什么返回。
  • if 语句让我觉得你混淆了 .map() 和 .filter()。 map 应该 always 返回一个值,而 filter 用于返回一个数组,该数组只包含满足您的条件的元素
  • map 做了一些完全不同的事情。你为什么要首先使用它? “我确实尝试过使用 .filter(),但它似乎返回的是原始数据而不是计算出来的数据” 就像你的代码一样。你的意思是什么?

标签: javascript loops for-loop dictionary ecmascript-6


【解决方案1】:

for 循环中的 return 语句会导致您的函数返回。但是,.map() 函数回调中的 return 语句仅返回回调,然后将返回的值放入新数组中。请参阅documentation。如果你真的想使用 .map(),你可以这样做:

export const fetchPollOptById = (id) => {
    var result;
    fakeChartData.map(data => {
        data.poll.map(data => {
            if (data.id === id) {
                result = data;
                return data;
            }
        });
    });
    return result;
}

注意:我还假设您的投票对象具有这样的 id 字段:

  fakeChartData = [
      {
          id: '232fsd23rw3sdf23r',
          title: 'blabla',
          poll: [
              {id: 'pollId1', otherField: 'blah'},
              {id: 'pollId2', otherField: 'blah'}
          ]
      },
      {
          id: '23dgsdfg3433sdf23r',
          title: 'againBla',
          poll: [
              {id: 'pollId3', otherField: 'blah'},
              {id: 'pollId4', otherField: 'blah'}
          ]
      }
  ];

然后您可以像这样获取投票数据:

fetchPollOptById("pollId3"); //returns {id: "pollId3", otherField: "blah"}

【讨论】:

  • 我现在知道了,但还是谢谢。虽然,你的答案接近我想要的,但我已经接受了别人的答案,但如果我能再做一次,那将是你的答案。干杯
  • 您可以选择更改接受的答案,因为您是问题的作者,但只有在您认为我的回答对您更有帮助时才这样做。见meta.stackexchange.com/questions/93969/…
【解决方案2】:

如果我对你想要做的事情是正确的,这应该有效:

return fakeChartData.reduce((acc, data) => acc.concat(data.poll), [])
                    .filter(pollObj => pollObj.id === id)[0]

首先它创建一个包含来自不同数据对象的所有轮询对象的数组,然后过滤它们以找到具有正确 id 的对象并返回该对象。

至于为什么您使用map 的方法不起作用:您以错误的方式使用它。 map 做了什么来获取一个函数并将其应用于数组的每个成员。

这是一个类似于你的数组和函数:

const arr = [1,2,3]
const getThingById(id) => {
  var mappedArray = arr.map(x => {
    if(x === id) return x
  })
  console.log(mappedArray) // [3]
}
getThingById(3) // undefined

这行不通。 getThingById 没有返回语句。 return 语句return x从传递给 map 的函数中返回一些东西。基本上,你不应该使用map 来做你想做的事情。 map 用于返回数组时。

【讨论】:

  • 这行得通,但我正在研究为什么 .map() 不起作用。我已经有了使用普通 for 循环的示例。
  • 您的带有 map 的示例不起作用,因为 return 语句仅退出第二个回调。两个回调仍然会迭代整个数组。您将从示例中获得的数组将仅包含未定义的。 map
  • @R.Schmitt 感谢您的解释。其他人只是给了我他们的解决方案,而没有“因为”。谢谢
  • @otajor 我会接受你的回答,它是最短的,也是不可变的。
  • 为接受而干杯——我刚刚编辑了一些关于为什么地图不起作用的更多解释。我建议您多阅读一些关于 mapfilterreduceforEach 的内容,并弄清楚何时应该使用它们。
【解决方案3】:

试试这个

fakeChartData.map(data => {
    var result = data.poll.map(data => {
      if (data.id === id) {
        return data;
      }
    });
    return result;
  });

它应该工作。是的,我认为你应该使用find() 而不是map()

【讨论】:

  • .find 不受 IE 支持
【解决方案4】:

实现有点长:

let results = fakeChartData.map(data => {
    let innerResult = data.poll.filter(data => {
      if (data.id === id) {
        return data;
      }
     return innerResult.length ? innerResult[0] : null;
    });
  })
  .filter(x => (x !== null));
let whatYouwant = results.lenght ? results[0] : null;

如果你可以使用 find() 会更好看,但这取决于你需要支持的浏览器

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-28
    • 2021-03-01
    • 2015-02-03
    • 2013-07-20
    • 1970-01-01
    • 1970-01-01
    • 2022-11-19
    • 2015-05-21
    相关资源
    最近更新 更多