如何在 javascript 中的自定义 Array.reduce() 中重写 Array.every()?

How to rewrite an Array.every() in a custom Array.reduce() in javascript?

本题纯属学习。 funfunfunction 在 youtube 上说

Any list higher order list transformation can be written in Array.reduce()

Audio/video参考:https://youtu.be/Wl98eZpkp-c?t=138

问题:

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

重写 Array.every()

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

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'

我对存储当前传递的值的位置感到困惑。我在哪里存储 "passed" 值,就像 Array.every() 一样?

 function every(previousValue, currentValue, currentIdx, arr) {
      if(previousValue.dateApproved !== null && currentValue.dateApproved !== null) {
        return currentValue;
      }
    }
 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')

这应该可以解决问题:

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

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

array.reduce

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

Array.reduce 有 4 个参数。

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

以下是显示插图的示例:

注:

  • 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')

你可以大致实现如下

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));