【问题标题】:How to rewrite an Array.every() in a custom Array.reduce() in javascript?如何在javascript中的自定义 Array.reduce() 中重写 Array.every()?
【发布时间】:2016-10-20 05:51:02
【问题描述】:

这个问题纯粹是为了学习目的。 youtube 上的funfunfunction

任何列表高阶列表变换都可以写成Array.reduce()

音频/视频参考:https://youtu.be/Wl98eZpkp-c?t=138

问题:

纯粹是为了学习如何用Array.reduce()重写Array.every()

这个问题源于我之前的问题here

Javascript 示例:

var approved1 = [

    {
        dateApproved: new Date(),
        id: 1,
    },
    {
        dateApproved: new Date(),
        id: 2,
    }
];

var approved2 = [

    {
        dateApproved: null,
        id: 1,
    },
    {
        dateApproved: new Date(),
        id: 2,
    }
];

approved1.every(a => a.dateApproved != null) ? 'APPROVED' : 'PENDING'
// 'APPROVED'
approved2.reduce(every) ? 'APPROVED' : 'PENDING'
// 'PENDING'

我为存储当前传递的值而苦恼。我在哪里存储像Array.every() 这样的“通过”值?

 function every(previousValue, currentValue, currentIdx, arr) {
      if(previousValue.dateApproved !== null && currentValue.dateApproved !== null) {
        return currentValue;
      }
    }

【问题讨论】:

  • 那么,你有什么尝试?
  • @JaromandaX 我会在 2 分钟内更新并 ping。
  • 3 点我会在我家的车里 :p
  • 您期望 reduce 的结果是什么?传递给回调的第一个参数是一个累加器,它将传递上一次调用的返回值(或者,如果未指定,将是数组中的第一个元素)。如果 reduce 函数没有返回任何东西(即没有 return 语句),它将是 undefined。请参阅ECMA–262MDN
  • @RobG 我认为最终的返回值将是单一的真或假。如果每个测试用例都通过,则确定该值。问题是,Array.every() 将那些中间通过或失败的测试用例存储在哪里。而且,最后只返回一个值?

标签: javascript arrays ecmascript-6 higher-order-functions


【解决方案1】:

您可以使用reduce 而不是every 并使其工作,但我建议您在适当的地方使用它们。两者都有独特的要求。

array.reduce

array.reduce(callback(curentElement, nextElement, index, array),[initialCurrentElement])

Array.reduce 有 4 个参数。

  • currentElement:默认情况下,这将是第一次迭代的数组中的第一个元素,然后,此变量将保存您返回的值。如果传递了一个初始值,那么它将保存该值并从那里开始。
  • nextElement:默认情况下它包含第二个或下一个元素。如果传递了初始值,它将保留第一个值。
  • index:保存当前元素的索引。
  • 数组:这是我们正在循环的父数组。
  • initialCurrentElement:这是一个可选参数。如果 this 被通过,则循环从 this 开始。

以下是显示插图的示例:

注意:

  • Array.every 将在第一个 falsey 条件下中断。 Array.reduce 不会。
  • Array.reduce 用于比较同一数组的 2 个值,而 Array.every 用于将每个值与一个表达式进行比较。使用 .reduce 而不是 .every 只是一种矫枉过正。

var approved2 = [{
  dateApproved: null,
  id: 1,
}, {
  dateApproved: new Date(),
  id: 2,
}];

var everyResult = approved2.every(x => {
  console.log(x.dateApproved)
  x.dateApproved !== null
})

console.log(everyResult)

var reduceResult = approved2.reduce((p, c) => {
  console.log(c.dateApproved)
  return !p ? p : c.dateApproved !== null
}, true)

console.log(reduceResult? 'Approved': 'Rejected')

【讨论】:

  • 哦,是的,我完全明白它已经结束了 kill reduce,这个问题只是为了更好地理解 reduce 的一个 excersize
  • @Rajesh - OP 提到他只是想学习这个:)
  • @nikjohn 是的。这些是警告。我添加了一个突出显示 1 个主要区别的答案。 .every 将在第一个虚假情况下停止。减少不会。所以你必须假设 firstArg 为布尔值而不是将其视为对象
  • @rajesh 这个previousValue 是布尔值的区别已经澄清了很多!泰泰!
  • 请注意,您的“currentElement”实际上是累加器,在ECMA-262 中称为“previousValue”。您的“nextElement”称为“currentValue”。我认为最好使用规范术语以避免混淆。此外,“Array.reduce 用于比较 2 个值”是错误的,它旨在将数组缩减为单个值。
【解决方案2】:

这应该可以解决问题:

function every(pre, curr) {
  return pre.dateApproved != null && curr.dateApproved != null
}

approved1.reduce(every) ? 'APPROVED' : 'PENDING' // APPROVED
approved2.reduce(every) ? 'APPROVED' : 'PENDING' // PENDING

而且我很确定你可以不用curr,只需pre

【讨论】:

  • 正确答案,但获得的答案更简洁!感谢您的帮助!
  • 请通过 nikjohn 的答案查看 cmets。这是一个错误的解决方案
【解决方案3】:
 var status = approved1.reduce(  val  =>  (val.dateApproved) ? 'APPROVED': 'REJECTED')

var approved1 = [

    {
        dateApproved: new Date(),
        id: 1,
    },
    {
        dateApproved: new Date(),
        id: 2,
    }
];

var approved2 = [

    {
        dateApproved: new Date(),
        id: 1,
    },
    {
        dateApproved: null,
        id: 2,
    },
{
        dateApproved: new Date(),
        id: 2,
    }
];

console.log(approved2.reduce(  (prev, curr)  =>  (prev.dateApproved && curr.dateApproved) ? true : false) ? 'APPROVED':'REJECTED')

console.log(approved1.reduce(  (prev, curr)  =>  (prev.dateApproved && curr.dateApproved) ? true : false) ? 'APPROVED':'REJECTED')

【讨论】:

  • 这是一个很好的答案。我“认为”我终于明白了 Array.reduce() 的第一个参数“previousValue”是如何工作的。感谢您的简洁回答。
  • .reduce 接受 2 个参数。 currentElement, nextElement。如果我颠倒 approved2 的顺序,您的解决方案将失败
  • 倒序是什么意思?
  • @nikjohn 你仍然在返回字符串,然后比较 string.dateApproved 这将产生 undefined
  • @MatthewHarwood 他的意思是如果数组中对象的顺序发生变化,即如果 null 出现在第一个元素而不是第二个元素中,依此类推。但更新后的答案应该可以处理所有此类情况
【解决方案4】:

你可以大致实现如下

Array.prototype.every = function(cb){
  return this.reduce((p,c,i,a) => i === 1 ? cb(p,i-1,a) && cb(c,i,a)
                                          : p && cb(c,i,a));
};

var arr = [9,2,3,9,12,5],
    brr = [1,2,3,4,5,6,9];
console.log(arr.every(e => e < 10));
console.log(brr.every(e => e < 10));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-11-06
    • 2023-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多