super-utils-plus
Version:
A superior alternative to Lodash with improved performance, TypeScript support, and developer experience
119 lines (118 loc) • 3.56 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.intersection = intersection;
exports.intersectionDeep = intersectionDeep;
exports.intersectionBy = intersectionBy;
const is_1 = require("../utils/is");
/**
* Creates an array of unique values that are included in all given arrays.
*
* @param arrays - The arrays to inspect
* @returns The new array of intersecting values
*
* @example
* ```ts
* intersection([2, 1], [2, 3]);
* // => [2]
* ```
*/
function intersection(...arrays) {
if (!arrays.length) {
return [];
}
if (arrays.length === 1) {
return [...new Set(arrays[0])];
}
const result = [];
const [first, ...rest] = arrays;
// Use a Set for better performance when checking the first array
const uniqueFirst = [...new Set(first)];
for (const item of uniqueFirst) {
// Check if item is in all other arrays
if (rest.every(array => array.includes(item))) {
result.push(item);
}
}
return result;
}
/**
* Creates an array of unique values that are included in all given arrays
* using deep equality comparison.
*
* @param arrays - The arrays to inspect
* @returns The new array of intersecting values
*
* @example
* ```ts
* intersectionDeep([{ 'x': 1 }, { 'x': 2 }], [{ 'x': 1 }, { 'x': 3 }]);
* // => [{ 'x': 1 }]
* ```
*/
function intersectionDeep(...arrays) {
if (!arrays.length) {
return [];
}
if (arrays.length === 1) {
return [...new Set(arrays[0])];
}
const [first, ...rest] = arrays;
const result = [];
// Create a new array with unique values from the first array
const uniqueFirst = [];
for (const item of first) {
if (!uniqueFirst.some(uniqueItem => (0, is_1.isEqual)(uniqueItem, item))) {
uniqueFirst.push(item);
}
}
for (const item of uniqueFirst) {
// Check if item is in all other arrays using deep equality
if (rest.every(array => array.some(arrayItem => (0, is_1.isEqual)(arrayItem, item)))) {
result.push(item);
}
}
return result;
}
/**
* Creates an array of unique values that are included in all given arrays
* using a custom iteratee function.
*
* @param arrays - The arrays to inspect with the last array being a function or property name
* @returns The new array of intersecting values
*
* @example
* ```ts
* intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor);
* // => [2.1]
*
* intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
* // => [{ 'x': 1 }]
* ```
*/
function intersectionBy(...arrays) {
if (arrays.length <= 1) {
return [];
}
const iteratee = arrays.pop();
const iterateeFn = typeof iteratee === 'function'
? iteratee
: (obj) => obj[iteratee];
const [first, ...rest] = arrays;
const result = [];
// Create a map of transformed values to the original item for the first array
const firstMap = new Map();
for (const item of first) {
const transformed = iterateeFn(item);
if (!firstMap.has(transformed)) {
firstMap.set(transformed, []);
}
firstMap.get(transformed).push(item);
}
// Check each transformed value against other arrays
for (const [key, items] of firstMap.entries()) {
if (rest.every(array => array.some(item => (0, is_1.isEqual)(iterateeFn(item), key)))) {
// Add all items with this transformed value
result.push(...items);
}
}
return result;
}