I'm designing an isIn
method that takes a value:any
and checks whether it exists in an array. It's working, but I'm wondering whether I missed any edge cases:
/**
* Checks if given value is in the target array of allowed values.
*
* @param value The value being checked.
* @param target The target value to perform the check against.
* @return True if the value is in the target array, false otherwise.
*/
export function isIn(value: any, target: any[]): boolean {
if (!isArray(value)) {
return !isArray(target) || target.indexOf(value)>-1;
}
else {
return (JSON.stringify(target)).indexOf(JSON.stringify(value)) != -1;
}
}
describe("isIn", () => {
it(`should return true when the value is in the array`, () => {
expect(isIn(2, [2])).to.be.true;
expect(isIn('a', ['a', 'b'])).to.be.true;
expect(isIn('a', ['a'])).to.be.true;
expect(isIn([2,3], [[2,3]])).to.be.true;
});
it(`should return false when the value is not in the array`, () => {
expect(isIn('a', ['b'])).to.be.false;
expect(isIn([2,4], [[2,3]])).to.be.false;
});
});
-
2\$\begingroup\$ I have rolled back your last edit. Please don't change or add to the code in your question after you have received answers. See What should I do when someone answers my question? Thank you. \$\endgroup\$Phrancis– Phrancis2018年07月08日 00:18:30 +00:00Commented Jul 8, 2018 at 0:18
1 Answer 1
Objects
One edge case you didn't test is isIn({property: 'value'}, [{property: 'value'}])
. I don't know what you want it to do here, but currently it will return false
.
You also did not test what happens when no values are passed in, or just a value. While TypeScript may not agree with not passing values to functions that are asking for them, it seems to still be possible.
And another one: JSON.stringify
has it's own quirks
- If undefined, a Function, or a Symbol is encountered during conversion it is either omitted (when it is found in an object) or censored to null (when it is found in an array). JSON.stringify can also just return undefined when passing in "pure" values like JSON.stringify(function(){}) or JSON.stringify(undefined).
- All Symbol-keyed properties will be completely ignored, even when using the replacer function.
- The instances of Date implement the toJSON() function by returning a string (the same as date.toISOString()), thus they are treated as strings.
- The numbers Infinity and NaN as well as the object null are all considered as null.
- For all the other Object instances (including Map, Set, WeakMap and WeakSet), only their enumerable properties will be serialized.
-
\$\begingroup\$ Thanks - I updated the code in the question adding a check for object along with updated typedoc and also noted the reliance on JSON.tostring. \$\endgroup\$Ole– Ole2018年07月07日 23:30:34 +00:00Commented Jul 7, 2018 at 23:30
-
1\$\begingroup\$
.stringify
not.tostring
\$\endgroup\$andria_girl– andria_girl2018年07月08日 00:22:05 +00:00Commented Jul 8, 2018 at 0:22 -
\$\begingroup\$ It's baked in! npmjs.com/package/@fireflysemantics/is \$\endgroup\$Ole– Ole2018年07月08日 01:42:25 +00:00Commented Jul 8, 2018 at 1:42