Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add pick, omit, pickBy, and omitBy functions #27

Merged
merged 2 commits into from
Nov 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions docs/collection/omit-by.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# omitBy

Creates a new object by omitting key-value pairs based on a predicate function.

### Usage

```ts
import { omitBy } from 'rattail'

omitBy({ a: 1, b: 2, c: 3 }, (value) => value > 1)
// return { a: 1 }
```

### Arguments

| Arg | Type | Defaults |
| -------- | -------------------------------------- | -------- |
| `object` | `object` | |
| `fn` | `(value: any, key: string) => boolean` | |

### Return

| Type |
| -------- |
| `object` |
25 changes: 25 additions & 0 deletions docs/collection/omit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# omit

Creates a new object by omitting specified keys from an existing object.

### Usage

```ts
import { omit } from 'rattail'

omit({ a: 1, b: 2, c: 3 }, ['a', 'c'])
// return { b: 2 }
```

### Arguments

| Arg | Type | Defaults |
| -------- | ---------- | -------- |
| `object` | `object` | |
| `keys` | `string[]` | |

### Return

| Type |
| -------- |
| `object` |
25 changes: 25 additions & 0 deletions docs/collection/pick-by.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# pickBy

Creates a new object by picking key-value pairs based on a predicate function.

### Usage

```ts
import { pickBy } from 'rattail'

pickBy({ a: 1, b: 2, c: 3 }, (value) => value > 1)
// return { b: 2, c: 3 }
```

### Arguments

| Arg | Type | Defaults |
| -------- | -------------------------------------- | -------- |
| `object` | `object` | |
| `fn` | `(value: any, key: string) => boolean` | |

### Return

| Type |
| -------- |
| `object` |
25 changes: 25 additions & 0 deletions docs/collection/pick.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# pick

Creates a new object by selecting specified keys from an existing object.

### Usage

```ts
import { pick } from 'rattail'

pick({ a: 1, b: 2, c: 3 }, ['a', 'c'])
// return { a: 1, c: 3 }
```

### Arguments

| Arg | Type | Defaults |
| -------- | ---------- | -------- |
| `object` | `object` | |
| `keys` | `string[]` | |

### Return

| Type |
| -------- |
| `object` |
25 changes: 25 additions & 0 deletions docs/zh/collection/omit-by.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# omitBy

通过提供的谓词函数排除键值对来创建新对象。

### 使用

```ts
import { omitBy } from 'rattail'

omitBy({ a: 1, b: 2, c: 3 }, (value) => value > 1)
// return { a: 1 }
```

### 参数

| 参数 | 类型 | 默认值 |
| -------- | -------------------------------------- | ------ |
| `object` | `object` | |
| `fn` | `(value: any, key: string) => boolean` | |

### 返回值

| 类型 |
| -------- |
| `object` |
25 changes: 25 additions & 0 deletions docs/zh/collection/omit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# omit

通过从现有对象中排除指定键来创建新对象。

### 使用

```ts
import { omit } from 'rattail'

omit({ a: 1, b: 2, c: 3 }, ['a', 'c'])
// return { b: 2 }
```

### 参数

| 参数 | 类型 | 默认值 |
| -------- | ---------- | ------ |
| `object` | `object` | |
| `keys` | `string[]` | |

### 返回值

| 类型 |
| -------- |
| `object` |
25 changes: 25 additions & 0 deletions docs/zh/collection/pick-by.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# pickBy

通过提供的谓词函数选择键值对来创建新对象。

### 使用

```ts
import { pickBy } from 'rattail'

pickBy({ a: 1, b: 2, c: 3 }, (value) => value > 1)
// return { b: 2, c: 3 }
```

### 参数

| 参数 | 类型 | 默认值 |
| -------- | -------------------------------------- | ------ |
| `object` | `object` | |
| `fn` | `(value: any, key: string) => boolean` | |

### 返回值

| 类型 |
| -------- |
| `object` |
25 changes: 25 additions & 0 deletions docs/zh/collection/pick.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# pick

通过从现有对象中选择指定键来创建新对象。

### 使用

```ts
import { pick } from 'rattail'

pick({ a: 1, b: 2, c: 3 }, ['a', 'c'])
// return { a: 1, c: 3 }
```

### 参数

| 参数 | 类型 | 默认值 |
| -------- | ---------- | ------ |
| `object` | `object` | |
| `keys` | `string[]` | |

### 返回值

| 类型 |
| -------- |
| `object` |
19 changes: 19 additions & 0 deletions src/collection/omit-by.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
export function omitBy<T>(
collection: T,
fn: (value: T extends any[] ? T[number] : T[keyof T], key: number | keyof T) => boolean,
): Partial<T> | T[] | undefined {
if (Array.isArray(collection)) {
return collection.filter((value, index) => !fn(value as T extends any[] ? T[number] : T[keyof T], index))
}

if (typeof collection === 'object' && collection !== null) {
const allKeys = [...Object.keys(collection), ...Object.getOwnPropertySymbols(collection)] as (keyof T)[]
return allKeys.reduce((result, key) => {
const value = collection[key]
if (!fn(value as T extends any[] ? T[number] : T[keyof T], key)) {
;(result as Partial<T>)[key] = value
}
return result
}, {} as Partial<T>)
}
}
15 changes: 15 additions & 0 deletions src/collection/omit.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export function omit<T extends object, K extends keyof T>(object: T, keys: K[]): Omit<T, K> {
const keysToOmit = new Set(keys)
const result = {} as Omit<T, K>
console.log(Object.keys(object))

const ownKeys = [...Object.keys(object), ...Object.getOwnPropertySymbols(object)] as (keyof T)[]

ownKeys.forEach((key) => {
if (!keysToOmit.has(key as K)) {
;(result as T)[key] = object[key]
}
})

return result
}
12 changes: 12 additions & 0 deletions src/collection/pick-by.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export function pickBy<T>(collection: T, fn: (value: any, key: keyof T) => boolean): Partial<T> | undefined {
if (typeof collection === 'object' && collection !== null) {
const allKeys = [...Object.keys(collection), ...Object.getOwnPropertySymbols(collection)] as (keyof T)[]
return allKeys.reduce((result, key) => {
const value = collection[key]
if (fn(value, key)) {
;(result as Partial<T>)[key] = value
}
return result
}, {} as Partial<T>)
}
}
9 changes: 9 additions & 0 deletions src/collection/pick.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export function pick<T, K extends keyof T>(object: T, keys: K[]): Pick<T, K> {
return keys.reduce(
(result, key) => {
result[key] = object[key]
return result
},
{} as Pick<T, K>,
)
}
2 changes: 0 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,3 @@ export * from './string'
export * from './collection'
export * from './file'
export * from './math'
export * from 'mitt'
export { default as mitt } from 'mitt'
117 changes: 116 additions & 1 deletion tests/collection.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { describe, it, expect } from 'vitest'
import { merge, mergeWith, cloneDeep, cloneDeepWith, isNumber, hasOwn } from '../src'
import { merge, mergeWith, cloneDeep, cloneDeepWith, isNumber, hasOwn, pick, omit, pickBy, omitBy } from '../src'

it('should merge two objects', () => {
const result = merge({ a: 1, b: { c: 2 } }, { b: { d: 3 }, e: 4 })
Expand Down Expand Up @@ -344,3 +344,118 @@
expect(result).toEqual({ a: 2, b: 3 })
})
})

describe('pick', () => {
it('should pick specified string keys from an object', () => {
const obj = { a: 1, b: 2, c: 3 }
const result = pick(obj, ['a', 'c'])

Check failure on line 351 in tests/collection.spec.ts

View workflow job for this annotation

GitHub Actions / test

tests/collection.spec.ts > pick > should pick specified string keys from an object

TypeError: pick is not a function ❯ tests/collection.spec.ts:351:20
expect(result).toEqual({ a: 1, c: 3 })
})

it('should pick specified symbol keys from an object', () => {
const symA = Symbol('a')
const symB = Symbol('b')
const obj = {
[symA]: 'valueA',
[symB]: 'valueB',
c: 3,
}

const result = pick(obj, [symA])

Check failure on line 364 in tests/collection.spec.ts

View workflow job for this annotation

GitHub Actions / test

tests/collection.spec.ts > pick > should pick specified symbol keys from an object

TypeError: pick is not a function ❯ tests/collection.spec.ts:364:20
expect(result).toEqual({
[symA]: 'valueA',
})
})

it('should pick elements by index from an array', () => {
const arr = [10, 20, 30, 40, 50]
const result = pick(arr, [0, 2, 4])

Check failure on line 372 in tests/collection.spec.ts

View workflow job for this annotation

GitHub Actions / test

tests/collection.spec.ts > pick > should pick elements by index from an array

TypeError: pick is not a function ❯ tests/collection.spec.ts:372:20
expect(result).toEqual({
'0': 10,
'2': 30,
'4': 50,
})
})
})

describe('omit', () => {
it('should omit specified string keys from an object', () => {
const obj = { a: 1, b: 2, c: 3 }
const result = omit(obj, ['b'])

Check failure on line 384 in tests/collection.spec.ts

View workflow job for this annotation

GitHub Actions / test

tests/collection.spec.ts > omit > should omit specified string keys from an object

TypeError: omit is not a function ❯ tests/collection.spec.ts:384:20
expect(result).toEqual({ a: 1, c: 3 })
})

it('should omit specified symbol keys from an object', () => {
const symA = Symbol('a')
const symB = Symbol('b')
const obj = {
[symA]: 'valueA',
[symB]: 'valueB',
c: 3,
}

const result = omit(obj, [symA])

Check failure on line 397 in tests/collection.spec.ts

View workflow job for this annotation

GitHub Actions / test

tests/collection.spec.ts > omit > should omit specified symbol keys from an object

TypeError: omit is not a function ❯ tests/collection.spec.ts:397:20
expect(result).toEqual({
[symB]: 'valueB',
c: 3,
})
})

it('should omit elements by index from an array', () => {
const arr = [10, 20, 30, 40, 50]
const result = omit(arr, [1, 3])

Check failure on line 406 in tests/collection.spec.ts

View workflow job for this annotation

GitHub Actions / test

tests/collection.spec.ts > omit > should omit elements by index from an array

TypeError: omit is not a function ❯ tests/collection.spec.ts:406:20
expect(result).toEqual([10, 30, 50])
})
})

describe('pickBy', () => {
it('should pick properties from an object based on the predicate for string keys', () => {
const obj = { a: 1, b: 2, c: 3 }
const result = pickBy(obj, (value) => value % 2 === 1)

Check failure on line 414 in tests/collection.spec.ts

View workflow job for this annotation

GitHub Actions / test

tests/collection.spec.ts > pickBy > should pick properties from an object based on the predicate for string keys

TypeError: pickBy is not a function ❯ tests/collection.spec.ts:414:20
expect(result).toEqual({ a: 1, c: 3 })
})

it('should pick properties from an object based on the predicate for symbol keys', () => {
const symA = Symbol('a')
const symB = Symbol('b')
const obj = {
[symA]: 1,
[symB]: 2,
c: 3,
}
const result = pickBy(obj, (value) => value === 2)

Check failure on line 426 in tests/collection.spec.ts

View workflow job for this annotation

GitHub Actions / test

tests/collection.spec.ts > pickBy > should pick properties from an object based on the predicate for symbol keys

TypeError: pickBy is not a function ❯ tests/collection.spec.ts:426:20
expect(result).toEqual({ [symB]: 2 })
})

it('should pick elements from an array based on the predicate', () => {
const arr: number[] = [10, 15, 20, 25, 30] // Explicitly specify the array as number[]
const result = pickBy(arr, (value) => value > 15)

Check failure on line 432 in tests/collection.spec.ts

View workflow job for this annotation

GitHub Actions / test

tests/collection.spec.ts > pickBy > should pick elements from an array based on the predicate

TypeError: pickBy is not a function ❯ tests/collection.spec.ts:432:20
expect(result).toEqual([20, 25, 30])
})
})

describe('omitBy', () => {
it('should omit properties from an object based on the predicate for string keys', () => {
const obj = { a: 1, b: 2, c: 3 }
const result = omitBy(obj, (value) => value % 2 === 1)

Check failure on line 440 in tests/collection.spec.ts

View workflow job for this annotation

GitHub Actions / test

tests/collection.spec.ts > omitBy > should omit properties from an object based on the predicate for string keys

TypeError: omitBy is not a function ❯ tests/collection.spec.ts:440:20
expect(result).toEqual({ b: 2 })
})

it('should omit properties from an object based on the predicate for symbol keys', () => {
const symA = Symbol('a')
const symB = Symbol('b')
const obj = {
[symA]: 1,
[symB]: 2,
c: 3,
}
const result = omitBy(obj, (value) => value === 2)
expect(result).toEqual({ [symA]: 1, c: 3 })
})

it('should omit elements from an array based on the predicate', () => {
const arr = [10, 15, 20, 25, 30]
const result = omitBy(arr, (value) => value < 20)
expect(result).toEqual([20, 25, 30])
})
})
Loading