Skip to content

Commit

Permalink
feat(micro-dash): add intersection()
Browse files Browse the repository at this point in the history
Closes #48
  • Loading branch information
ersimont committed Jul 14, 2021
1 parent 14417df commit 1c9a715
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 1 deletion.
@@ -0,0 +1,3 @@
import intersection from 'lodash-es/intersection';

console.log(intersection([1, 2], [2, 3], null));
@@ -0,0 +1,3 @@
import { intersection } from '@s-libs/micro-dash';

console.log(intersection([1, 2], [2, 3], null));
2 changes: 1 addition & 1 deletion projects/micro-dash/README.md
Expand Up @@ -39,7 +39,7 @@ Below are the main differences between the implementations in this library compa
- There is no shorthand for "iteratees"; functions that accept one require you to provide an actual function.
- Does not pass the iterated object to iteratee functions. This allows simplifications, e.g. methods like `merge` can be used as an iteratee for `reduce` without being guarded.
- It has no special knowledge of "array like" objects; only actual arrays are treated as arrays.
- Makes no special attempts to preserve the sign of `-0`.
- Makes no special attempt to treat `0` and `-0` differently.
- String functions are designed for simple cases like variable names. They only treat `[0-9A-Za-z]` as part of words and are not smart about contractions or ordinals (e.g. `I'll` or `1st`).
- A modern environment/buildchain is assumed. E.g. this project uses ES6 functions directly. If you target older browsers/environments, you may need to include polyfills separately. However, it will only use features that _can_ be polyfilled.

Expand Down
1 change: 1 addition & 0 deletions projects/micro-dash/src/lib/array/index.ts
Expand Up @@ -4,6 +4,7 @@ export { concat } from './concat';
export { difference } from './difference';
export { flatten } from './flatten';
export { initial } from './initial';
export { intersection } from './intersection';
export { last } from './last';
export { nth } from './nth';
export { pull } from './pull';
Expand Down
61 changes: 61 additions & 0 deletions projects/micro-dash/src/lib/array/intersection.spec.ts
@@ -0,0 +1,61 @@
import { constant, range, times } from 'lodash-es';
import { intersection } from './intersection';

describe('intersection()', () => {
it('works with null and undefined', () => {
const array = [0, 1, null, 3];
expect(intersection(array, null)).toEqual([]);
expect(intersection(array, undefined)).toEqual([]);
expect(intersection(null, array)).toEqual([]);
expect(intersection(undefined, array)).toEqual([]);
expect(intersection(null)).toEqual([]);
expect(intersection(undefined)).toEqual([]);
});

//
// stolen from https://github.com/lodash/lodash
//

it('should return the intersection of two arrays', () => {
expect(intersection([2, 1], [2, 3])).toEqual([2]);
});

it('should return the intersection of multiple arrays', () => {
expect(intersection([2, 1, 2, 3], [3, 4], [3, 2])).toEqual([3]);
});

it('should return an array of unique values', () => {
expect(intersection([1, 1, 3, 2, 2], [5, 2, 2, 1, 4], [2, 1, 1])).toEqual([
1, 2,
]);
});

it('should work with a single array', () => {
expect(intersection([1, 1, 3, 2, 2])).toEqual([1, 3, 2]);
});

it('should match `NaN`', () => {
expect(intersection([1, NaN, 3], [NaN, 5, NaN])).toEqual([NaN]);
});

it('should work with large arrays of `NaN`', () => {
const largeArray = times(200, () => NaN);
expect(intersection([1, NaN, 3], largeArray)).toEqual([NaN]);
});

it('should work with large arrays of objects', () => {
const object = {};
const largeArray = times(200, constant(object));

expect(intersection([object], largeArray)).toEqual([object]);
expect(intersection(range(200), [1])).toEqual([1]);
});

it('should return an array', () => {
const array = [1, 2, 3];
const actual = intersection(array);

expect(actual).toEqual(jasmine.any(Array));
expect(actual).not.toBe(array);
});
});
13 changes: 13 additions & 0 deletions projects/micro-dash/src/lib/array/intersection.ts
@@ -0,0 +1,13 @@
import { Nil } from '../interfaces';

/**
* Creates an array of unique values that are included in all given arrays using SameValueZero for equality comparisons. The order and references of result values are determined by the first array.
*
* Contribution to minified bundle size, when it is the only function imported:
* - Lodash: 5,789 bytes
* - Micro-dash: 115 bytes
*/
export function intersection<T>(...arrays: Array<readonly T[] | Nil>): T[] {
const sets = arrays.map((array) => new Set(array));
return [...sets[0]].filter((value) => sets.every((set) => set.has(value)));
}

0 comments on commit 1c9a715

Please sign in to comment.