JavaScript Array.every() does not work the way I expected
I have been tasked with writing a basic check for GUID validity without using regex. So all I'm doing is checking if the non-dash characters in the guid string are hexa digits.
const isValidGUIDChar = (char) => !isNaN(+char) || "abcdef".includes(char.toLowerCase());
// let guid = "123";
// let guid = "abc"
let guid = "abc123";
let isGuidValid = guid.replaceAll('-', '').length === 32 && guid.split().every(isValidGUIDChar);
console.log(isGuidValid); // returns true for either 'abc' or '123' but false for 'abc123'
The results, mention in comment above are counter-intuitive. The every() method seems to evaluate to:
"(every character must either be numeric), or (every character must be from among 'abcdef')",
whereas what I need, and what seems intuitive, would be for it to evaluate to:
"(every character) must (either be numeric from among 'abcdef')"
How can I accomplish the latter?
.split() is missing "" (BTW, use [...guid] with Spread instead)isGuidValid(guid) - reusability, remember?const isHEX = (ch) => "0123456789abcdef".includes(ch.toLowerCase());
const isGuidValid = (guid) => {
guid = guid.replaceAll("-", ""); // Format it first!
return guid.length === 32 && [...guid].every(isHEX);
};
console.log(isGuidValid("adec3dc3-7025-4905-b584-d9e64117f2fd")); // true
console.log(isGuidValid("adec3dc3-7025-4905-b584-d9e64117f2fz")); // false
console.log(isGuidValid("adec3dc3-7025-4905-b584-d9e64117f2f")); // false
A more robust approach, taking in consideration the RFC4122 treating a GIUD/UUID as groups of 8-4-4-4-12 codepoint chars each would be:
const isHEX = h => !isNaN(parseInt(h, 16));
const RFC4122Len = [8, 4, 4, 4, 12];
const isGuidValid = (guid) => {
// Must have 36 Chars per codepoint (32 + 4 dashes)
const codePointLenght = [...guid].length;
if (codePointLenght !== 36) return false;
// Must have 5 groups
const groups = guid.split("-");
if (groups.length !== 5) return false;
// RFC defines 5 groups of 8-4-4-4-12 codepoints chars each
const lenMatch = groups.map(gr => [...gr].length).every((len, i) => len === RFC4122Len[i]);
if (!lenMatch) return false;
// Finally join groups (without the "-" separators and check for each char is HEX)
return [...(groups.join(""))].every(isHEX);
};
console.log(isGuidValid("adec3dc3-7025-4905-b584-d9e64117f2fd")); // true
console.log(isGuidValid("adec3dc3-7025-4905-b584-d9e64117f2fz")); // false
console.log(isGuidValid("adec3dc3-7025-4905-b584-d9e64117f2f")); // false
There's more to make it fully RFC4122 compliant but you got the general idea.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With