From 73d1cea28612677b42b4e506402533abe4cd893e Mon Sep 17 00:00:00 2001 From: Tsah Date: Mon, 10 Aug 2026 09:53:27 +0300 Subject: [PATCH] feat: add collection helpers and email validation --- node/collections.js | 16 ++++++++++++++++ python/emails.py | 14 ++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 node/collections.js create mode 100644 python/emails.py diff --git a/node/collections.js b/node/collections.js new file mode 100644 index 0000000..a1e9ca7 --- /dev/null +++ b/node/collections.js @@ -0,0 +1,16 @@ +export function groupBy(items, keyFn) { + return items.reduce((acc, item) => { + const key = keyFn(item); + (acc[key] ||= []).push(item); + return acc; + }, {}); +} + +export function partition(items, predicate) { + const pass = []; + const fail = []; + for (const item of items) { + (predicate(item) ? pass : fail).push(item); + } + return [pass, fail]; +} diff --git a/python/emails.py b/python/emails.py new file mode 100644 index 0000000..f284367 --- /dev/null +++ b/python/emails.py @@ -0,0 +1,14 @@ +import re + +EMAIL_RE = re.compile(r"^[^@\s]+@[^@\s]+\.[^@\s]+$") + + +def is_valid_email(value): + return bool(EMAIL_RE.match(value)) + + +def normalize_email(value): + if not is_valid_email(value): + raise ValueError("invalid email address") + local, domain = value.split("@", 1) + return f"{local}@{domain.lower()}"