问题
This question is for purely for learning purposes. funfunfunction on youtube says that
Any list higher order list transformation can be written in Array.reduce()
Audio/video Reference: https://youtu.be/Wl98eZpkp-c?t=138.
Question:
Purely for learning how would one rewrite Array.every() with Array.reduce()
This question stems from my previous question here
Javascript Example:
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'
I struggle with where I store the currently passed values. Where do I store the "passed" values like Array.every()
does?
function every(previousValue, currentValue, currentIdx, arr) {
if(previousValue.dateApproved !== null && currentValue.dateApproved !== null) {
return currentValue;
}
}
回答1:
You can use reduce
instead of every
and make it work, but I'd suggest you to use them in there apt places. Both have distinctive requirement.
array.reduce
array.reduce(callback(curentElement, nextElement, index, array),[initialCurrentElement])
Array.reduce has 4 args.
- currentElement: By default, this will be 1st element in array for 1st iteration and then, this variable will hold value that you return. If an initial value is passed, then it will hold that and start from there.
- nextElement: By default it holds second or next element. If initial value is passed, this will hold first value.
- index: this holds the index of current element.
- array: This is the parent array on which we are looping.
- initialCurrentElement: This is an optional argument. If this is passed, looping starts with this.
Following is a sample showing an illustration:
Note:
Array.every
will break on firstfalsey
condition. Array.reduce will not.Array.reduce
is meant to compare 2 values of same array where asArray.every
is meant to compare each values to an expression. Using.reduce
instead of.every
is just an overkill.
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')
回答2:
This should do the trick:
function every(pre, curr) {
return pre.dateApproved != null && curr.dateApproved != null
}
approved1.reduce(every) ? 'APPROVED' : 'PENDING' // APPROVED
approved2.reduce(every) ? 'APPROVED' : 'PENDING' // PENDING
And I'm pretty sure you can do it without curr
, just pre
.
回答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')
回答4:
You might roughly implement it as folows
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));
来源:https://stackoverflow.com/questions/40146430/how-to-rewrite-an-array-every-in-a-custom-array-reduce-in-javascript