【问题标题】:Why is JS Map Function Returning Undefined? [duplicate]为什么 JS Map 函数返回未定义? [复制]
【发布时间】:2018-05-11 00:17:17
【问题描述】:

我有一个长度约为 1000 的数组。为什么 map 函数在某些索引中返回未定义?有没有办法只返回满足这个条件的数组?我想返回一个值 > 0 的数组。

 var total_percents = cars.map(function(element) {
        var savings_percent = Number(element[0].getAttribute("percent-savings"));
        if (savings_percent > 0)
            return savings_percent;
});

【问题讨论】:

  • 您只为条件的一侧返回一个值。如果savings_percent <= 0 怎么办?看起来您可能想要使用 reduce 而不是 map
  • map 的结果将是一个与原始长度相同的数组。如果map 回调未返回值,则结果在该索引处未定义。听起来你想先过滤
  • 如果 savings_percent 为 undefined。您可以使用filter 只返回想要的元素,或使用reduce 一次处理所有元素。
  • 您希望total_percents 的值是多少?单个数字、数字数组还是 car 值数组(无论它们是什么)?

标签: javascript jquery arrays


【解决方案1】:

您需要在映射后过滤值,您可以使用 filter 数组方法和 car => car > 0 这样的谓词来完成

var total_percents = cars.map((element) => Number(element[0].getAttribute("percent-savings"))).filter(car => car > 0)

您也可以使用reduce 方法同时组合这两个操作:

var total_percents =
  cars.reduce((acc, element) => {
    const percentSavings = Number(element[0].getAttribute("percent-savings"));

    if (percentSavings > 0) {
      acc.push(percentSavings);
    }

    return acc;
  }, [])

【讨论】:

  • 对此需要稍作修正。 OP 想要超过 0 的值,但这将返回任何 truthy 值,包括负数。试试car => car > 0
  • 这效率低下,因为您要枚举列表两次,请使用 Array.prototype.reduce 查看我的回答
  • @fabbb 问题与终极性能或性能无关。
  • @fabbb 但无论如何我都在编辑我的答案以添加reduce 版本,甚至在你评论之前:)
  • 非常感谢凯伦!!答案也很好!如果你有时间,你能看看这个帖子吗?我仍然有这个问题!整天被困在这上面哈哈stackoverflow.com/questions/50278228/…
【解决方案2】:

不确定您要完成什么,但是:

尝试这样的方法来返回所有 pctSavings 的总和:

const totalPercents = cars.reduce((sum, el) => {
    const pctSavings = +(el[0].getAttribute("percent-savings"));
    if (pctSavings > 0) sum += pctSavings;
    return sum;
}, 0);

要返回一个 pctSavings 数组,只需执行以下操作:

const totalPercents = cars.reduce((arr, el) => {
    const pctSavings = +(el[0].getAttribute("percent-savings"));
    if (pctSavings > 0) arr.push(pctSavings);
    return arr;
}, []);

要获得最大 pctSavings,请执行以下操作:

let maxPctSavings = 0;
cars.forEach(el => {
    const pctSavings = +(el[0].getAttribute("percent-savings"));
    if (pctSavings > maxPctSavings) maxPctSavings = pctSavings
});
console.log(maxPctSavings) // this is your answer

【讨论】:

  • 嗨 Fabb - 我的目标是节省所有百分比并找到 MAX
  • 其实我真的只需要最大值。想法?
  • 非常感谢! el[0]前面的+语法是什么?
  • 它是 Number() 的缩写,所以基本上,+'1' == Number('1')
  • 如果你有时间可以看看这篇文章吗?我仍然有这个问题! stackoverflow.com/questions/50278228/…
【解决方案3】:

使用reduce 过滤和映射值(应该比单独的filtermap 更快并且使用更少的内存)

var total_percents = cars.reduce(
  function(out, element) {
    var savings_percent = Number(element[0].getAttribute("percent-savings"));
    if (savings_percent > 0) {
      // Only add to the out-array if value is greater than 0.
      out.push(savings_percent);
    }
    return out;
  },
  [] // start with empty array
);

total_percents 将是一个数组,其值大于 0。

阅读对另一个答案的评论,您想要的是最大节省。 然后我会这样做:

var max_savings = cars.reduce(
  function(value, element) {
    var savings_percent = Number(element[0].getAttribute("percent-savings"));
    return Math.max(savings_percent, value)
  },
  0 // start with no savings
);

【讨论】:

    【解决方案4】:

    如果参数不能转换为数字,“Number”将返回“NaN”(非数字)。然后,您使用字符串“NaN”的数字比较“>”与您的零值进行比较,因此比较失败并且不会返回,因此会出现“未定义”。您可以进行双重比较 - if (typeof Savings_percent == 'string'

    if (typeof savings_percent == 'number' && savings_percent > 0)
    

    【讨论】:

    • 如果参数不能转换为数字,Number 将返回 NaN 是正确的,但它是 NOT 字符串。 typeof Number('string')numberNaN 是一个特殊的值,它不等于任何东西,甚至不等于它自己:NaN == NaNfalse
    • 而且typeof NaN也是number,最好用新的闪亮Number.isNaN()方法检查NaN,以避免旧isNaN的陷阱
    • 谢谢凯伦,我忘了 isNaN() 方法!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-07
    • 1970-01-01
    • 2021-01-14
    • 2018-07-11
    • 2020-12-25
    • 2020-03-28
    相关资源
    最近更新 更多