-
Notifications
You must be signed in to change notification settings - Fork 326
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' into imp/invariant
- Loading branch information
Showing
14 changed files
with
383 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import { describe, expect, it } from 'vitest'; | ||
import { flattenArrayLike } from './flattenArrayLike'; | ||
|
||
describe('flattenArrayLike', () => { | ||
it('should flatten an array of array-like objects', () => { | ||
const input: Array<ArrayLike<string>> = [ | ||
{ length: 3, 0: 'a', 1: 'b', 2: 'c' }, | ||
{ length: 2, 0: 'd', 1: 'e' }, | ||
{ length: 0 }, | ||
]; | ||
const expectedOutput = ['a', 'b', 'c', 'd', 'e']; | ||
expect(flattenArrayLike(input)).toEqual(expectedOutput); | ||
}); | ||
|
||
it('should ignore non-array-like objects', () => { | ||
const input: any[] = [{ length: 2, 0: 'x', 1: 'y' }, 3, { length: 1, 0: 'z' }]; | ||
const expectedOutput = ['x', 'y', 'z']; | ||
expect(flattenArrayLike(input)).toEqual(expectedOutput); | ||
}); | ||
|
||
it('should return an empty array when input is empty', () => { | ||
const input: Array<ArrayLike<any>> = []; | ||
const expectedOutput: any[] = []; | ||
expect(flattenArrayLike(input)).toEqual(expectedOutput); | ||
}); | ||
|
||
it('should handle nested array-like objects', () => { | ||
const input: Array<ArrayLike<number[]>> = [ | ||
{ length: 2, 0: [1, 2], 1: [3, 4] }, | ||
{ length: 1, 0: [5, 6] }, | ||
]; | ||
const expectedOutput = [ | ||
[1, 2], | ||
[3, 4], | ||
[5, 6], | ||
]; | ||
expect(flattenArrayLike(input)).toEqual(expectedOutput); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { isArrayLikeObject } from '../predicate/isArrayLikeObject.ts'; | ||
|
||
export function flattenArrayLike<T>(values: Array<ArrayLike<T>>): T[] { | ||
const result: T[] = []; | ||
|
||
for (let i = 0; i < values.length; i++) { | ||
const arrayLike = values[i]; | ||
|
||
if (!isArrayLikeObject(arrayLike)) { | ||
continue; | ||
} | ||
|
||
for (let j = 0; j < arrayLike.length; j++) { | ||
result.push(arrayLike[j]); | ||
} | ||
} | ||
|
||
return result; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
import { describe, expect, it } from 'vitest'; | ||
import { uniqBy } from './uniqBy'; | ||
import { LARGE_ARRAY_SIZE } from '../_internal/LARGE_ARRAY_SIZE'; | ||
|
||
/** | ||
* @see https://github.com/lodash/lodash/blob/6a2cc1dfcf7634fea70d1bc5bd22db453df67b42/test/uniqBy-methods.spec.js | ||
*/ | ||
describe('uniqBy', () => { | ||
const objects = [{ a: 2 }, { a: 3 }, { a: 1 }, { a: 2 }, { a: 3 }, { a: 1 }]; | ||
|
||
it('should work with a `mapper`', () => { | ||
expect(uniqBy([2.1, 1.2, 2.3], Math.floor)).toEqual([2.1, 1.2]); | ||
expect(uniqBy([1.2, 1.5, 2.1, 3.2, 5.7, 5.3, 7.19], Math.floor)).toEqual([1.2, 2.1, 3.2, 5.7, 7.19]); | ||
}); | ||
|
||
it('should work with an iteratee function', () => { | ||
const expected = objects.slice(0, 3); | ||
const actual = uniqBy(objects, (object: { a: any }) => object.a); | ||
expect(actual).toEqual(expected); | ||
}); | ||
|
||
it('should work with property shorthands (string)', () => { | ||
const expected = objects.slice(0, 3); | ||
const actual = uniqBy(objects, 'a'); | ||
expect(actual).toEqual(expected); | ||
}); | ||
|
||
it('should work with property shorthands (number)', () => { | ||
const arrays = [[2], [3], [1], [2], [3], [1]]; | ||
const expected = arrays.slice(0, 3); | ||
const actual = uniqBy(arrays, 0); | ||
expect(actual).toEqual(expected); | ||
}); | ||
|
||
it('should work with large arrays', () => { | ||
const largeArray = Array.from({ length: LARGE_ARRAY_SIZE }, () => [1, 2]); | ||
const actual = uniqBy(largeArray, JSON.stringify); | ||
expect(actual.length).toBe(1); | ||
expect(actual[0]).toEqual([1, 2]); | ||
}); | ||
|
||
it('should provide correct iteratee arguments', () => { | ||
let args: any; | ||
uniqBy(objects, (...params: any[]) => { | ||
if (!args) { | ||
args = params; | ||
} | ||
}); | ||
expect(args).toEqual([objects[0]]); | ||
}); | ||
|
||
it('should return an array with the first element when iteratee returns the same value for all elements', () => { | ||
const actual = uniqBy(objects, () => 'same'); | ||
expect(actual).toEqual([objects[0]]); | ||
}); | ||
|
||
describe('should return an empty array when iteratee returns various types', () => { | ||
const testCases = { | ||
'an array': [0, 'a'], | ||
'an object': { '0': 'a' }, | ||
'a number': 0, | ||
'a string': '0', | ||
}; | ||
|
||
Object.entries(testCases).forEach(([key, value]) => { | ||
it(`should return an empty array when iteratee returns ${key}`, () => { | ||
const actual = uniqBy(objects, () => value); | ||
|
||
expect(actual).toEqual([objects[0]]); | ||
}); | ||
}); | ||
}); | ||
|
||
it('should return an empty array if the first array is null or undefined', () => { | ||
expect(uniqBy(null as any, 'a')).toEqual([]); | ||
expect(uniqBy(undefined as any, 'a')).toEqual([]); | ||
}); | ||
|
||
it('should handle empty arrays correctly', () => { | ||
expect(uniqBy([], 'a')).toEqual([]); | ||
expect(uniqBy([], Math.floor)).toEqual([]); | ||
}); | ||
|
||
it('should handle single-element arrays correctly', () => { | ||
const singleElement = [{ a: 1 }]; | ||
expect(uniqBy(singleElement, 'a')).toEqual(singleElement); | ||
expect(uniqBy(singleElement, (obj: { a: any }) => obj.a)).toEqual(singleElement); | ||
}); | ||
|
||
it('should not mutate the original array', () => { | ||
const original = [...objects]; | ||
uniqBy(objects, 'a'); | ||
expect(objects).toEqual(original); | ||
}); | ||
}); |
Oops, something went wrong.