diff --git a/docs/ja/reference/compat/array/flattenDepth.md b/docs/ja/reference/compat/array/flattenDepth.md index 1551c72d5..8ee4defe5 100644 --- a/docs/ja/reference/compat/array/flattenDepth.md +++ b/docs/ja/reference/compat/array/flattenDepth.md @@ -11,12 +11,22 @@ ## インターフェース ```typescript -function flattenDepth(value: T[] | object, depth: D): Array> | []; +function flattenDepth(value: T[], depth: D): Array> | []; ``` ### パラメータ -- `value` (`T[] | object`): フラット化する値。 +- `value` (`T[]`): フラット化する値。 + +::: info `value` は `ArrayLike`、`null`、または `undefined` になります。 + +lodash との完全な互換性を確保するため、`flattenDepth` 関数は `value` を次のように処理します。 + +- `value` が `ArrayLike` の場合、`Array.from(...)` を使用して配列に変換されます。 +- `value` が `null` または `undefined` の場合、空の配列として扱われます。 + +::: + - `depth` (`D`): ネストされた配列構造をどの深さまでフラット化するかを指定する深さレベル。デフォルトは1です。 ### 戻り値 diff --git a/docs/ja/reference/compat/array/slice.md b/docs/ja/reference/compat/array/slice.md index ce79aea40..0521aff93 100644 --- a/docs/ja/reference/compat/array/slice.md +++ b/docs/ja/reference/compat/array/slice.md @@ -19,6 +19,16 @@ function slice(array: T[], start?: number, end?: number): T[]; ### パラメータ - `array` (`T[]`): 部分配列を作成する配列。 + +::: info `array` は `ArrayLike`、`null`、または `undefined` になります。 + +lodash との完全な互換性を確保するため、`slice` 関数は `array` を次のように処理します。 + +- `array` が `ArrayLike` の場合、`Array.from(...)` を使用して配列に変換されます。 +- `array` が `null` または `undefined` の場合、空の配列として扱われます。 + +::: + - `start` (`number`): 開始位置。デフォルトは `0` です。 - `end` (`number`): 終了位置。デフォルトは `array.length` です。 diff --git a/docs/ja/reference/compat/array/zipObjectDeep.md b/docs/ja/reference/compat/array/zipObjectDeep.md index 93135eaae..919af1e71 100644 --- a/docs/ja/reference/compat/array/zipObjectDeep.md +++ b/docs/ja/reference/compat/array/zipObjectDeep.md @@ -13,13 +13,13 @@ ## インターフェース ```typescript -function zipObjectDeep

(keys: P[], values: V[]): { [K in P]: V }; +function zipObjectDeep

(keys: ArrayLike

, values: ArrayLike): { [K in P]: V }; ``` ### パラメータ -- `keys` (`P[]`): プロパティパスを含む配列。 -- `values` (`V[]`): 対応する値を含む配列。 +- `keys` (`ArrayLike

`): プロパティパスを含む配列。 +- `values` (`ArrayLike`): 対応する値を含む配列。 ### 戻り値 diff --git a/docs/ko/reference/compat/array/flattenDepth.md b/docs/ko/reference/compat/array/flattenDepth.md index 8899f121c..3db910536 100644 --- a/docs/ko/reference/compat/array/flattenDepth.md +++ b/docs/ko/reference/compat/array/flattenDepth.md @@ -11,12 +11,22 @@ ## 인터페이스 ```typescript -function flattenDepth(value: T[] | object, depth: D): Array> | []; +function flattenDepth(value: T[], depth: D): Array> | []; ``` ### 파라미터 -- `value` (`T[] | object`): 평평하게 할 값이에요. +- `value` (`T[]`): 평평하게 할 값이에요. + +::: info `value`는 `ArrayLike`, `null`, 또는 `undefined`가 될 수 있어요. + +lodash와 완전한 호환성을 보장하기 위해, `flattenDepth` 함수는 `value`를 다음과 같이 처리해요. + +- `value`가 `ArrayLike`인 경우, `Array.from(...)`을 사용하여 배열로 변환돼요. +- `value`가 `null` 또는 `undefined`인 경우, 빈 배열로 처리돼요. + +::: + - `depth` (`D`): 중첩 배열 구조가 얼마나 깊게 평평해져야 하는지 지정하는 깊이 수준이에요. 기본값은 1이에요. ### 반환 값 diff --git a/docs/ko/reference/compat/array/slice.md b/docs/ko/reference/compat/array/slice.md index 6b8785488..0bb428e20 100644 --- a/docs/ko/reference/compat/array/slice.md +++ b/docs/ko/reference/compat/array/slice.md @@ -19,6 +19,16 @@ function slice(array: T[], start?: number, end?: number): T[]; ### 파라미터 - `array` (`T[]`): 부분 배열을 만들 배열. + +::: info `array`는 `ArrayLike`, `null`, 또는 `undefined`가 될 수 있어요. + +lodash와 완전한 호환성을 보장하기 위해, `slice` 함수는 `array`를 다음과 같이 처리해요. + +- `array`가 `ArrayLike`인 경우, `Array.from(...)`을 사용하여 배열로 변환돼요. +- `array`가 `null` 또는 `undefined`인 경우, 빈 배열로 처리돼요. + +::: + - `start` (`number`): 시작 위치. 기본값은 `0`이에요. - `end` (`number`): 끝 위치. 기본값은 `array.length`예요. diff --git a/docs/ko/reference/compat/array/zipObjectDeep.md b/docs/ko/reference/compat/array/zipObjectDeep.md index dc23bc2f7..c1dcd4bcf 100644 --- a/docs/ko/reference/compat/array/zipObjectDeep.md +++ b/docs/ko/reference/compat/array/zipObjectDeep.md @@ -13,13 +13,13 @@ ## 인터페이스 ```typescript -function zipObjectDeep

(keys: P[], values: V[]): { [K in P]: V }; +function zipObjectDeep

(keys: ArrayLike

, values: ArrayLike): { [K in P]: V }; ``` ### 파라미터 -- `keys` (`P[]`): 프로퍼티 경로가 포함된 배열. -- `values` (`V[]`): 값에 대응되는 값이 포함된 배열. +- `keys` (`ArrayLike

`): 프로퍼티 경로가 포함된 배열. +- `values` (`ArrayLike`): 값에 대응되는 값이 포함된 배열. ### 반환 값 diff --git a/docs/reference/compat/array/flattenDepth.md b/docs/reference/compat/array/flattenDepth.md index 8a6e26cb9..e2f574e89 100644 --- a/docs/reference/compat/array/flattenDepth.md +++ b/docs/reference/compat/array/flattenDepth.md @@ -11,12 +11,22 @@ Flattens an array up to the specified depth. ## Signature ```typescript -function flattenDepth(value: T[] | object, depth: D): Array> | []; +function flattenDepth(value: T[], depth: D): Array> | []; ``` ### Parameters -- `value` (`T[] | object`): The value to flatten. +- `value` (`T[]`): The value to flatten. + +::: info `value` can be `ArrayLike`, `null`, or `undefined` + +To ensure full compatibility with lodash, the `flattenDepth` function handles `value` in this way: + +- If `value` is an `ArrayLike`, it gets converted into an array using `Array.from(...)`. +- If `value` is `null` or `undefined`, it will be treated as an empty array. + +::: + - `depth` (`D`): The depth level specifying how deep a nested array structure should be flattened. Defaults to 1. ### Returns diff --git a/docs/reference/compat/array/slice.md b/docs/reference/compat/array/slice.md index 45aa54541..3e479c159 100644 --- a/docs/reference/compat/array/slice.md +++ b/docs/reference/compat/array/slice.md @@ -19,6 +19,16 @@ function slice(array: T[], start?: number, end?: number): T[]; ### Parameters - `array` (`T[]`): The array to slice. + +::: info `array` can be `ArrayLike`, `null`, or `undefined` + +To ensure full compatibility with lodash, the `slice` function handles `array` in this way: + +- If `array` is an `ArrayLike`, it gets converted into an array using `Array.from(...)`. +- If `array` is `null` or `undefined`, it will be treated as an empty array. + +::: + - `start` (`number`): The start position. Defaults to `0`. - `end` (`number`): The end position. Defaults to `array.length`. diff --git a/docs/reference/compat/array/zipObjectDeep.md b/docs/reference/compat/array/zipObjectDeep.md index 196ace33d..669caf4ed 100644 --- a/docs/reference/compat/array/zipObjectDeep.md +++ b/docs/reference/compat/array/zipObjectDeep.md @@ -15,13 +15,13 @@ Paths can be dot-separated strings or arrays of property names. If the `keys` ar ## Signature ```typescript -function zipObjectDeep

(keys: P[], values: V[]): { [K in P]: V }; +function zipObjectDeep

(keys: ArrayLike

, values: ArrayLike): { [K in P]: V }; ``` ### Parameters -- `keys` (`P[]`): An array of property names. -- `values` (`V[]`): An array of values corresponding to the property names. +- `keys` (`ArrayLike

`): An array of property names. +- `values` (`ArrayLike`): An array of values corresponding to the property names. ### Returns diff --git a/docs/zh_hans/reference/compat/array/flattenDepth.md b/docs/zh_hans/reference/compat/array/flattenDepth.md index 702442f9b..ac98ee519 100644 --- a/docs/zh_hans/reference/compat/array/flattenDepth.md +++ b/docs/zh_hans/reference/compat/array/flattenDepth.md @@ -11,12 +11,22 @@ ## 签名 ```typescript -function flattenDepth(value: T[] | object, depth: D): Array> | []; +function flattenDepth(value: T[], depth: D): Array> | []; ``` ### 参数 -- `value` (`T[] | object`): 要展平的值。 +- `value` (`T[]`): 要展平的值。 + +::: info `value` 可以是 `ArrayLike`、`null` 或 `undefined`。 + +为了确保与 lodash 的完全兼容性,`flattenDepth` 函数以以下方式处理 `value`: + +- 如果 `value` 是 `ArrayLike`,则会使用 `Array.from(...)` 将其转换为数组。 +- 如果 `value` 是 `null` 或 `undefined`,则会将其视为一个空数组。 + +::: + - `depth` (`D`): 指定嵌套数组结构展平深度的级别。默认值为1。 ### 返回值 diff --git a/docs/zh_hans/reference/compat/array/slice.md b/docs/zh_hans/reference/compat/array/slice.md index 8de7b8659..9493d5931 100644 --- a/docs/zh_hans/reference/compat/array/slice.md +++ b/docs/zh_hans/reference/compat/array/slice.md @@ -19,6 +19,16 @@ function slice(array: T[], start?: number, end?: number): T[]; ### 参数 - `array` (`T[]`): 用于创建部分数组的数组。 + +::: info `array` 可以是 `ArrayLike`、`null` 或 `undefined`。 + +为了确保与 lodash 的完全兼容性,`slice` 函数以以下方式处理 `array`: + +- 如果 `array` 是 `ArrayLike`,则会使用 `Array.from(...)` 将其转换为数组。 +- 如果 `array` 是 `null` 或 `undefined`,则会将其视为一个空数组。 + +::: + - `start` (`number`): 开始位置。默认值为 `0`。 - `end` (`number`): 结束位置。默认值为 `array.length`。 diff --git a/docs/zh_hans/reference/compat/array/zipObjectDeep.md b/docs/zh_hans/reference/compat/array/zipObjectDeep.md index 431976039..b75121a57 100644 --- a/docs/zh_hans/reference/compat/array/zipObjectDeep.md +++ b/docs/zh_hans/reference/compat/array/zipObjectDeep.md @@ -14,13 +14,13 @@ ## 签名 ```typescript -function zipObjectDeep

(keys: P[], values: V[]): { [K in P]: V }; +function zipObjectDeep

(keys: ArrayLike

, values: ArrayLike): { [K in P]: V }; ``` ### 参数 -- `keys` (`P[]`): 属性名称的数组。 -- `values` (`V[]`): 与属性名称对应的值的数组。 +- `keys` (`ArrayLike

`): 属性名称的数组。 +- `values` (`ArrayLike`): 与属性名称对应的值的数组。 ### 返回值 diff --git a/src/compat/array/flatten.spec.ts b/src/compat/array/flatten.spec.ts index 222eff47c..61ab97628 100644 --- a/src/compat/array/flatten.spec.ts +++ b/src/compat/array/flatten.spec.ts @@ -47,8 +47,14 @@ describe('flatten', () => { it('should return an empty array for non array-like objects', () => { const nonArray = { 0: 'a' }; const expected: [] = []; - const actual = flatten(nonArray); + const actual = flatten(nonArray as any); expect(actual).toEqual(expected); }); + + it('should support array-like', () => { + expect(flatten({ 0: [1, 2, 3], length: 1 })).toEqual([1, 2, 3]); + expect(flatten('123')).toEqual(['1', '2', '3']); + expect(flatten(args)).toEqual([1, 2, 3]); + }); }); diff --git a/src/compat/array/flatten.ts b/src/compat/array/flatten.ts index 4dda23983..c4bd1e2b6 100644 --- a/src/compat/array/flatten.ts +++ b/src/compat/array/flatten.ts @@ -1,9 +1,11 @@ +import { isArrayLike } from '../predicate/isArrayLike.ts'; + /** * Flattens an array up to the specified depth. * * @template T - The type of elements within the array. * @template D - The depth to which the array should be flattened. - * @param {T[] | object} value - The object to flatten. + * @param {ArrayLike | null | undefined} value - The object to flatten. * @param {D} depth - The depth level specifying how deep a nested array structure should be flattened. Defaults to 1. * @returns {Array> | []} A new array that has been flattened. * @@ -15,13 +17,13 @@ * // Returns: [1, 2, 3, 4, 5, 6] */ export function flatten( - value: readonly T[] | object, + value: ArrayLike | null | undefined, depth = 1 as D ): Array> | [] { const result: Array> = []; const flooredDepth = Math.floor(depth); - if (!Array.isArray(value)) { + if (!isArrayLike(value)) { return result; } @@ -45,7 +47,7 @@ export function flatten( } }; - recursive(value, 0); + recursive(Array.from(value), 0); return result; } diff --git a/src/compat/array/flattenDeep.spec.ts b/src/compat/array/flattenDeep.spec.ts index 350c7b5a8..5b77a1e4e 100644 --- a/src/compat/array/flattenDeep.spec.ts +++ b/src/compat/array/flattenDeep.spec.ts @@ -47,8 +47,14 @@ describe('flattenDeep', () => { it('should return an empty array for non array-like objects', () => { const nonArray = { 0: 'a' }; const expected: [] = []; - const actual = flattenDeep(nonArray); + const actual = flattenDeep(nonArray as any); expect(actual).toEqual(expected); }); + + it('should support array-like', () => { + expect(flattenDeep({ 0: [1, 2, [3]], length: 1 })).toEqual([1, 2, 3]); + expect(flattenDeep('123')).toEqual(['1', '2', '3']); + expect(flattenDeep(args)).toEqual([1, 2, 3]); + }); }); diff --git a/src/compat/array/flattenDeep.ts b/src/compat/array/flattenDeep.ts index 3d51ebb97..869c1c678 100644 --- a/src/compat/array/flattenDeep.ts +++ b/src/compat/array/flattenDeep.ts @@ -16,13 +16,13 @@ type ExtractNestedArrayType = T extends ReadonlyArray ? ExtractNeste * Flattens all depths of a nested array. * * @template T - The type of elements within the array. - * @param {T[] | object} value - The value to flatten. + * @param {ArrayLike} value - The value to flatten. * @returns {Array> | []} A new array that has been flattened. * * @example * const value = flattenDeep([1, [2, [3]], [4, [5, 6]]]); * // Returns: [1, 2, 3, 4, 5, 6] */ -export function flattenDeep(value: readonly T[] | object): Array> | [] { +export function flattenDeep(value: ArrayLike | null | undefined): Array> | [] { return flatten(value, Infinity) as Array>; } diff --git a/src/compat/array/flattenDepth.spec.ts b/src/compat/array/flattenDepth.spec.ts index 7355064bd..f83a87e3c 100644 --- a/src/compat/array/flattenDepth.spec.ts +++ b/src/compat/array/flattenDepth.spec.ts @@ -47,7 +47,7 @@ describe('flattenDepth', () => { it('should return an empty array for non array-like objects', () => { const nonArray = { 0: 'a' }; const expected: [] = []; - const actual = flattenDepth(nonArray, 2); + const actual = flattenDepth(nonArray as any, 2); expect(actual).toEqual(expected); }); @@ -68,4 +68,10 @@ describe('flattenDepth', () => { const array = [1, [2, [3, [4]], 5]]; expect(flattenDepth(array, 2.2)).toEqual([1, 2, 3, [4], 5]); }); + + it('should support array-like', () => { + expect(flattenDepth({ 0: [1, 2, 3], length: 1 })).toEqual([1, 2, 3]); + expect(flattenDepth('123')).toEqual(['1', '2', '3']); + expect(flattenDepth(args)).toEqual([1, 2, 3]); + }); }); diff --git a/src/compat/array/flattenDepth.ts b/src/compat/array/flattenDepth.ts index 349b4b602..4c3e304fd 100644 --- a/src/compat/array/flattenDepth.ts +++ b/src/compat/array/flattenDepth.ts @@ -5,7 +5,7 @@ import { flatten } from './flatten.ts'; * * @template T - The type of elements within the array. * @template D - The depth to which the array should be flattened. - * @param {T[] | object} value - The value to flatten. + * @param {ArrayLike | null | undefined} value - The value to flatten. * @param {D} depth - The depth level specifying how deep a nested array structure should be flattened. Defaults to 1. * @returns {Array> | []} A new array that has been flattened. * @@ -17,7 +17,7 @@ import { flatten } from './flatten.ts'; * // Returns: [1, 2, 3, 4, 5, 6] */ export function flattenDepth( - value: readonly T[] | object, + value: ArrayLike | null | undefined, depth = 1 as D ): Array> | [] { return flatten(value, depth); diff --git a/src/compat/array/slice.spec.ts b/src/compat/array/slice.spec.ts index a46afd329..fed9de462 100644 --- a/src/compat/array/slice.spec.ts +++ b/src/compat/array/slice.spec.ts @@ -1,5 +1,6 @@ import { describe, expect, it } from 'vitest'; import { slice } from './slice'; +import { args } from '../_internal/args'; import { falsey } from '../_internal/falsey'; describe('slice', () => { @@ -101,4 +102,10 @@ describe('slice', () => { expect(slice(null as any)).toEqual([]); expect(slice(undefined as any)).toEqual([]); }); + + it('should support array-like', () => { + expect(slice({ 0: 1, 1: 2, 2: 3, length: 3 })).toEqual([1, 2, 3]); + expect(slice('123')).toEqual(['1', '2', '3']); + expect(slice(args)).toEqual([1, 2, 3]); + }); }); diff --git a/src/compat/array/slice.ts b/src/compat/array/slice.ts index 42edea03c..1b065eebc 100644 --- a/src/compat/array/slice.ts +++ b/src/compat/array/slice.ts @@ -1,4 +1,5 @@ import { isIterateeCall } from '../_internal/isIterateeCall.ts'; +import { isArrayLike } from '../predicate/isArrayLike.ts'; import { toInteger } from '../util/toInteger.ts'; /** @@ -7,7 +8,7 @@ import { toInteger } from '../util/toInteger.ts'; * It does not return a dense array for sparse arrays unlike the native `Array.prototype.slice`. * * @template T - The type of the array elements. - * @param {T[]} array - The array to slice. + * @param {ArrayLike | null | undefined} array - The array to slice. * @param {number} [start=0] - The start position. * @param {number} [end=array.length] - The end position. * @returns {T[]} - Returns the slice of `array`. @@ -16,8 +17,8 @@ import { toInteger } from '../util/toInteger.ts'; * slice([1, 2, 3], 1, 2); // => [2] * slice(new Array(3)); // => [undefined, undefined, undefined] */ -export function slice(array: readonly T[], start?: number, end?: number): T[] { - if (array == null) { +export function slice(array: ArrayLike | null | undefined, start?: number, end?: number): T[] { + if (!isArrayLike(array)) { return []; } diff --git a/src/compat/array/zipObjectDeep.spec.ts b/src/compat/array/zipObjectDeep.spec.ts index ac7aba50f..3300f266e 100644 --- a/src/compat/array/zipObjectDeep.spec.ts +++ b/src/compat/array/zipObjectDeep.spec.ts @@ -37,4 +37,19 @@ describe('zipObject', () => { it('should support deep paths', () => { expect(zipObjectDeep(['a.b.c'], [1])).toEqual({ a: { b: { c: 1 } } }); }); + + it('should return an empty object when given null or undefined `keys`', () => { + expect(zipObjectDeep(null as any, [1])).toEqual({}); + expect(zipObjectDeep(undefined as any, [1])).toEqual({}); + }); + + it('should support array-like keys', () => { + expect(zipObjectDeep({ 0: ['a'], length: 1 }, [1])).toEqual({ a: 1 }); + expect(zipObjectDeep('12', [1, 2])).toEqual({ 1: 1, 2: 2 }); + }); + + it('should support array-like values', () => { + expect(zipObjectDeep(['a'], { 0: 1, length: 1 })).toEqual({ a: 1 }); + expect(zipObjectDeep(['a', 'b'], '12')).toEqual({ a: '1', b: '2' }); + }); }); diff --git a/src/compat/array/zipObjectDeep.ts b/src/compat/array/zipObjectDeep.ts index 2ea70cfe6..71c5ad143 100644 --- a/src/compat/array/zipObjectDeep.ts +++ b/src/compat/array/zipObjectDeep.ts @@ -1,5 +1,6 @@ import { zip } from '../../array/zip.ts'; import { set } from '../object/set.ts'; +import { isArrayLike } from '../predicate/isArrayLike.ts'; /** * Creates a deeply nested object given arrays of paths and values. @@ -12,9 +13,9 @@ import { set } from '../object/set.ts'; * * @template P - The type of property paths. * @template V - The type of values corresponding to the property paths. - * @param {P[] | P[][]} keys - An array of property paths, each path can be a dot-separated string or an array of property names. - * @param {V[]} values - An array of values corresponding to the property paths. - * @returns {object} A new object composed of the given property paths and values. + * @param {ArrayLike

} keys - An array of property paths, each path can be a dot-separated string or an array of property names. + * @param {ArrayLike} values - An array of values corresponding to the property paths. + * @returns {{ [K in P]: V }} A new object composed of the given property paths and values. * * @example * const paths = ['a.b.c', 'd.e.f']; @@ -35,11 +36,17 @@ import { set } from '../object/set.ts'; * // result will be { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } } */ export function zipObjectDeep

( - keys: readonly P[] | readonly P[][], - values: readonly V[] + keys: ArrayLike

, + values: ArrayLike ): { [K in P]: V } { const result = {} as { [K in P]: V }; - const zipped = zip

(keys, values); + if (!isArrayLike(keys)) { + return result; + } + if (!isArrayLike(values)) { + values = []; + } + const zipped = zip

(Array.from(keys), Array.from(values)); for (let i = 0; i < zipped.length; i++) { const [key, value] = zipped[i];