【问题标题】:Sum only those elements that passes the condition using map仅对那些使用 map 通过条件的元素求和
【发布时间】:2021-02-05 09:42:42
【问题描述】:

我有两个数组:
团队 A = [97, 112, 101]
团队 B = [109, 95, 123]

数组中的每个元素都是特定球队在一场比赛中的得分。我需要设置一个条件,仅将高于 100 的分数相加。因此,对于一个团队来说,条件是:如果团队得分高于 100,则该团队得分与另一个也高于 100 的团队得分相加,并且如果该得分的总和更高比另一队得分之和,该队获胜。

我坚信通过映射我可以得到高于 100 的分数,但我得到了一个新数组,其中第一个元素为 undefined。

我的代码示例:

const dolphinsGames = [97, 112, 101];
const koalasGames = [109, 95, 123];

const dolphinsScoreAbove = dolphinsGames.map((dolphinsGame) => {
if (dolphinsGame >= 100) {
    return dolphinsGame;
}
});
const koalasScoreAbove = koalasGames.map((koalasGame) => {
if (koalasGame >= 100) {
   return koalasGame;
}
});

结果是: enter image description here

【问题讨论】:

  • 请添加预期结果以便清晰理解...
  • “使用 map 仅对通过条件的元素求和” map 不是这项工作的正确工具。循环是这项工作的正确工具:let count = 0; for (const game of dolphinGames) { if (game >= 100) { ++count; } } 有些人也会使用reduce,但在使用预定义减速器的函数式编程之外,我不建议这样做——太容易出错。 (但 FWIW:let count = dolphinGames.reduce((game, count) => { if (game >= 100) { ++count; }; return count; }, 0);
  • 比较团队的平均分数以确定比赛的获胜者并将其打印到控制台。包括最低分数为 100 的要求。根据此规则,只有当一个团队的得分高于另一个团队并且同时得分至少为 100 分时,它才会获胜。我希望现在理解起来会更好。
  • @Vukasin - 恐怕不会。
  • 我尝试了过滤方法,效果很好。

标签: javascript arrays conditional-statements


【解决方案1】:

Array#map 返回一个与数组长度相同的新数组,并获取每个项目的回调结果。

相反,您可以使用 Array#filter 过滤数组并返回或不返回项目,具体取决于过滤器函数。

const
    valid = score => score >= 100,
    add = (a, b) => a + b,
    dolphinsGames = [97, 112, 101],
    koalasGames = [109, 95, 123],
    dolphinsScore = dolphinsGames.filter(valid).reduce(add, 0),
    koalasScore = koalasGames.filter(valid).reduce(add, 0);

console.log(dolphinsScore, koalasScore);

if (dolphinsScore === koalasScore) console.log('draw');
else if (dolphinsScore > koalasScore) console.log('dolphins won');
else console.log('koalas won');

【讨论】:

  • 嗯,问题是为什么 MAP 功能没有按预期工作。
  • MAP 方法转换数组的每一项,而过滤器方法用于选择数组中的某些项。
【解决方案2】:

你的 cmets 是你需要的吗?虽然没有使用地图:(

const dolphinsGames = [97, 112, 101];
const koalasGames = [109, 95, 123];

const average = arr => arr.reduce( ( p, c ) => p + c, 0 ) / arr.length;

const dolphinsAvg = average(dolphinsGames);
const koalasAvg = average(koalasGames);

if(dolphinsAvg > 100 && koalasAvg > 100){
    if(dolphinsAvg === koalasAvg){
    console.log('draw') 
  }
  else if(dolphinsAvg > koalasAvg ){
    console.log('dolphins win')
  }
  else{
   console.log('koalas win')
  }
}
else{
    console.log('Average points is less than 100')
}

【讨论】:

    【解决方案3】:

    您可以使用 filter() 方法实现您所尝试的目标。与 map() 不同,过滤器回调函数期望返回 true/false。因此,我会将您的程序修改为,

    const dolphinsGames = [97, 112, 101];
    const koalasGames = [109, 95, 123];
    
    const dolphinsScoreAbove = dolphinsGames.filter((dolphinsGame) => {
      if (dolphinsGame >= 100) {
          return true;
      }
      return false;
    });
    
    const koalasScoreAbove = koalasGames.filter((koalasGame) => {
      if (koalasGame >= 100) {
         return true;
      }
      return false;
    });
    
    console.log(dolphinsScoreAbove);
    console.log(koalasScoreAbove);

    【讨论】:

      【解决方案4】:

      Map 总是创建一个长度相同的数组,映射每个条目。在您的情况下,映射函数在您的“其他”情况下隐式返回 undefined。

      解决这个问题的一种方法是使用flatMap:

      dolphinGames.flatMap((dolphinGame) => dolphinGame >= 100 ? dolpinGame : [])
      

      编辑: 正如 cmets 中所讨论的,即使此示例正在运行,但更好的选择是简单的 filter,因为我们实际上并没有更改映射函数中的元素。

      【讨论】:

      • 仍然不满足的索引作为空数组返回。使用过滤器是这个用例的方式。
      • 不是[1,2,3].flatMap(n => n > 1 ? n : []) // [2,3]flatMap 将展平空数组。您也可以在 Mozilla 文档 developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… 上找到这种方法,但我同意在这种情况下过滤器是更好的选择。
      猜你喜欢
      • 1970-01-01
      • 2018-08-27
      • 2014-10-26
      • 2015-06-06
      • 1970-01-01
      • 2021-12-28
      • 1970-01-01
      • 2019-01-27
      • 1970-01-01
      相关资源
      最近更新 更多