-
-
Notifications
You must be signed in to change notification settings - Fork 110
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add is.any() and is.all() methods #19
Conversation
@kodie At the bottom of the issue sindresorhus explained his idea of any and all. You can check it out. For eg. any(is.string, {}, true, '🦄'); |
@melvin0008 oh shoot! Completely missed that. I will update my PR. |
Sure. is.any = (func, ...values) => values.some(func); is.all = (func, ...values) => values.every(func); |
PR Updated. 🍻 |
ah, using rest parameters break Node v4 support. :/ |
There we go 👍 |
index.js
Outdated
@@ -169,4 +169,30 @@ const isEmptyMapOrSet = x => (is.map(x) || is.set(x)) && x.size === 0; | |||
|
|||
is.empty = x => !x || isEmptyStringOrArray(x) || isEmptyObject(x) || isEmptyMapOrSet(x); | |||
|
|||
is.any = function (predicate, values) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- See Array.prototype.some for the predicate check.
- Take the values as an array using
(predicate, ...values) => { ... }
instead of the slice. - Use arrow functions instead of an anonymous function. All other methods use this syntax. You have to be consistent with the rest of the code.
basically, I think the code can look like is.any = (predicate, ...values) => values.some(predicate)
;
of course, you have to validate the values
is an array using is.array
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I now see that ...values
is impossible, So as I've said, put a comment stating the it's not possible due to node4 compatibility.
So keep the current logic, but use the array methods like before, and extract a common method to which you can pass the correct method (aka Array.prototype.some
or Array.prototype.every
).
index.js
Outdated
@@ -169,4 +169,30 @@ const isEmptyMapOrSet = x => (is.map(x) || is.set(x)) && x.size === 0; | |||
|
|||
is.empty = x => !x || isEmptyStringOrArray(x) || isEmptyObject(x) || isEmptyMapOrSet(x); | |||
|
|||
is.any = function (predicate, values) { | |||
let ret = false; | |||
values = Array.prototype.slice.call(arguments, 1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally, just a note, don't use arguments
, ES5 has given has enough ways to deprecate usage pf arguments
.
If you really end up having to use arguments
, make sure you document it well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gioragutt What would I use instead of arguments
if I can't use ...values
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Notice the comment I've made above. I wrote it before I've went over the commits.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gioragutt oh, gotcha!
index.js
Outdated
return ret; | ||
}; | ||
|
||
is.all = function (predicate, values) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Array.prototype.every, same as before.
@@ -402,3 +402,17 @@ test('is.empty', t => { | |||
tempSet.add(1); | |||
t.false(m.empty(tempSet)); | |||
}); | |||
|
|||
test('is.any', t => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing test cases:
- no items (aka
m.any(m.integer)
) - invalid predicate? what if the passed predicate is not a function? this should be validated
@sindresorhus say is.function(predicate) === false
, do we throw an Error?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
say is.function(predicate) === false, do we throw an Error?
Yes
test.js
Outdated
t.false(m.any(m.integer, true, 'lol', {})); | ||
}); | ||
|
||
test('is.all', t => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same as above
@gioragutt PR Updated again, let me know what you think. |
index.js
Outdated
@@ -169,4 +169,35 @@ const isEmptyMapOrSet = x => (is.map(x) || is.set(x)) && x.size === 0; | |||
|
|||
is.empty = x => !x || isEmptyStringOrArray(x) || isEmptyObject(x) || isEmptyMapOrSet(x); | |||
|
|||
const isAnyOrAll = (all, predicate, values) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of passing all
as a boolean, pass in a method
param instead.
this would actually be either Array.prototype.some
or Array.prototype.every
,
and you'd call method.call(values, predicate)
.
it makes sense more than passing a boolean. If we're speaking clean code and SOLID
, this violates both Single Responsibility Principle
and Open Close Principle
, because it makes isAnyOrAll
(which should be renamed, for the same reasons) responsible for both having the the calls to the methods inside of it, and needing the logic to decide which method is called.
By passing the method from the caller, we can allow more methods to use isAnyOrAll
.
I'm sure that there are more method of Array
that receive a predicate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense! What would you suggest we change the name of isAnyOrAll
to?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
predicateOnArray
index.js
Outdated
} | ||
|
||
if (values.length === 0) { | ||
throw new TypeError(`Invalid number of values: ${util.inspect(values.length)}`); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can never really have a value other than 0
, so why call inspect on this? instead, make the error more readable, f.e: No values passed to ${callerMethod}
, where callerMethod
can be passed as an argument.
|
||
// We have to use anonymous functions for the any() and all() methods | ||
// to get the arguments since we can't use rest parameters in node v4. | ||
is.any = function (predicate) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is.any = predicate => isAnyOrAll(...)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have to use an anonymous function in order to get the correct arguments object. For some reason the arguments object is weird with arrow functions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
God I hate old js.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Arrow functions dont have arguments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just for the sake of debugging, name the anonymous functions (isAll and isAny) so that they'll be named if they appear in a stack trace.
After that, I'll approve
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, we now have is.empty
for length === 0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just for the sake of debugging, name the anonymous functions (isAll and isAny) so that they'll be named if they appear in a stack trace.
That is not necessary. JS engines are able to infer the name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, we now have is.empty for length === 0
I think it's overdoing it using is.empty
for that.
@gioragutt Updated. |
|
||
// We have to use anonymous functions for the any() and all() methods | ||
// to get the arguments since we can't use rest parameters in node v4. | ||
is.any = function (predicate) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just for the sake of debugging, name the anonymous functions (isAll and isAny) so that they'll be named if they appear in a stack trace.
After that, I'll approve
|
||
// We have to use anonymous functions for the any() and all() methods | ||
// to get the arguments since we can't use rest parameters in node v4. | ||
is.any = function (predicate) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, we now have is.empty
for length === 0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sindresorhus If so, then this PR is done?
👌😎 |
@sindresorhus great! v0.3.0? |
Already done an hour ago ;) |
Here is the
any()
andall()
methods mentioned in #1.I wasn't 100% sure how you envisioned it working but the way I did it was both methods accepts two arrays as parameters so that it's possible to check multiple variables for multiple types.
Let me know if you were thinking something different!