From 618863ecf14b99e12ad9a055f91db2fe74d651a9 Mon Sep 17 00:00:00 2001 From: vigneshrajan94 Date: Wed, 27 May 2026 17:06:16 +0530 Subject: [PATCH] Fix median sort, set-op duplicates, and unescape Unicode range MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes three independent bugs: - Arithmetic.mjs (median): sort was only applied for even-length arrays; odd-length inputs returned the middle element of the unsorted array. Sort is now unconditional. Fixes #2239. - SetDifference / SetIntersection: plain .filter() on array a preserved duplicate entries from the first input, violating set semantics. Deduplicate a via [...new Set(a)] before filtering. Fixes #2241. - UnescapeUnicodeCharacters: regex quantifier was hardcoded to {4} for all prefixes. U+ notation allows 4-6 hex digits (e.g. U+1F600 for 😀); \u and %u remain at exactly {4} per their respective specs. Fixes #2242. --- src/core/lib/Arithmetic.mjs | 9 +++++---- src/core/operations/SetDifference.mjs | 2 +- src/core/operations/SetIntersection.mjs | 2 +- src/core/operations/UnescapeUnicodeCharacters.mjs | 3 ++- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/core/lib/Arithmetic.mjs b/src/core/lib/Arithmetic.mjs index 7c10855f..a1c2e181 100644 --- a/src/core/lib/Arithmetic.mjs +++ b/src/core/lib/Arithmetic.mjs @@ -108,10 +108,11 @@ export function mean(data) { * @returns {BigNumber} */ export function median(data) { - if ((data.length % 2) === 0 && data.length > 0) { - data.sort(function(a, b) { - return a.minus(b); - }); + if (data.length === 0) return data[0]; + data.sort(function(a, b) { + return a.minus(b); + }); + if ((data.length % 2) === 0) { const first = data[Math.floor(data.length / 2)]; const second = data[Math.floor(data.length / 2) - 1]; return mean([first, second]); diff --git a/src/core/operations/SetDifference.mjs b/src/core/operations/SetDifference.mjs index dc46c079..1c14a289 100644 --- a/src/core/operations/SetDifference.mjs +++ b/src/core/operations/SetDifference.mjs @@ -75,7 +75,7 @@ class SetDifference extends Operation { * @returns {Object[]} */ runSetDifference(a, b) { - return a + return [...new Set(a)] .filter((item) => { return b.indexOf(item) === -1; }) diff --git a/src/core/operations/SetIntersection.mjs b/src/core/operations/SetIntersection.mjs index 7e6dbe10..27a36aa7 100644 --- a/src/core/operations/SetIntersection.mjs +++ b/src/core/operations/SetIntersection.mjs @@ -75,7 +75,7 @@ class SetIntersection extends Operation { * @returns {Object[]} */ runIntersect(a, b) { - return a + return [...new Set(a)] .filter((item) => { return b.indexOf(item) > -1; }) diff --git a/src/core/operations/UnescapeUnicodeCharacters.mjs b/src/core/operations/UnescapeUnicodeCharacters.mjs index 02d16662..f7759c78 100644 --- a/src/core/operations/UnescapeUnicodeCharacters.mjs +++ b/src/core/operations/UnescapeUnicodeCharacters.mjs @@ -56,7 +56,8 @@ class UnescapeUnicodeCharacters extends Operation { */ run(input, args) { const prefix = prefixToRegex[args[0]], - regex = new RegExp(prefix+"([a-f\\d]{4})", "ig"); + quantifier = args[0] === "U+" ? "{4,6}" : "{4}", + regex = new RegExp(prefix+"([a-f\\d]"+quantifier+")", "ig"); let output = "", m, i = 0;