mirror of
https://github.com/toss/es-toolkit.git
synced 2024-11-24 03:32:58 +03:00
feat(property): Add property
This commit is contained in:
parent
13c7c7f611
commit
0e0329ac91
15
benchmarks/performance/property.bench.ts
Normal file
15
benchmarks/performance/property.bench.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { property as propertyToolkit } from 'es-toolkit/compat';
|
||||
import { property as propertyLodash } from 'lodash';
|
||||
import { bench, describe } from 'vitest';
|
||||
|
||||
describe('property', () => {
|
||||
bench('es-toolkit/property', () => {
|
||||
const getValue = propertyToolkit('a.b');
|
||||
getValue({ 'a.b': 1, a: { b: 1 } });
|
||||
})
|
||||
|
||||
bench('lodash/property', () => {
|
||||
const getValue = propertyLodash('a.b');
|
||||
getValue({ 'a.b': 1, a: { b: 1 } });
|
||||
})
|
||||
})
|
@ -150,6 +150,7 @@ function sidebar(): DefaultTheme.Sidebar {
|
||||
{ text: 'pickBy', link: '/reference/object/pickBy' },
|
||||
{ text: 'get (compat)', link: '/reference/compat/object/get' },
|
||||
{ text: 'set (compat)', link: '/reference/compat/object/set' },
|
||||
{ text: 'property (compat)', link: '/reference/compat/object/property' },
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -161,6 +161,7 @@ function sidebar(): DefaultTheme.Sidebar {
|
||||
{ text: 'pickBy', link: '/ko/reference/object/pickBy' },
|
||||
{ text: 'get (호환성)', link: '/ko/reference/compat/object/get' },
|
||||
{ text: 'set (호환성)', link: '/ko/reference/compat/object/set' },
|
||||
{ text: 'property (호환성)', link: '/ko/reference/compat/object/property' },
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -145,6 +145,7 @@ function sidebar(): DefaultTheme.Sidebar {
|
||||
{ text: 'pickBy', link: '/zh_hans/reference/object/pickBy' },
|
||||
{ text: 'get (兼容性)', link: '/zh_hans/reference/compat/object/get' },
|
||||
{ text: 'set (兼容性)', link: '/zh_hans/reference/compat/object/set' },
|
||||
{ text: 'property (兼容性)', link: '/zh_hans/reference/compat/object/property' },
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
객체에서 주어진 경로에 있는 값을 가져와요. 그 값이 `undefined` 라면, 기본값을 반환해요.
|
||||
|
||||
## Signature
|
||||
## 인터페이스
|
||||
|
||||
```typescript
|
||||
function get<T extends object, K extends keyof T>(object: T, path: K | [K]): T[K];
|
||||
|
35
docs/ko/reference/compat/object/property.md
Normal file
35
docs/ko/reference/compat/object/property.md
Normal file
@ -0,0 +1,35 @@
|
||||
# property
|
||||
|
||||
::: info
|
||||
이 함수는 [lodash와 완전히 호환](../../../compatibility.md)돼요. `es-toolkit/compat` 라이브러리에서 쓸 수 있어요.
|
||||
:::
|
||||
|
||||
객체에서 주어진 경로에 있는 값을 가져오는 함수를 만들어요. 값을 가져오기 위해서는 [`get`](./get.md) 함수를 사용해요.
|
||||
|
||||
## 인터페이스
|
||||
|
||||
```typescript
|
||||
function property(path: PropertyKey | readonly PropertyKey[]): (object: unknown) => any
|
||||
```
|
||||
|
||||
### 파라미터
|
||||
|
||||
- `path` (`string` or `number` or `symbol` or `Array<string | number | symbol>`): 프로퍼티를 가져올 경로.
|
||||
|
||||
### 반환 값
|
||||
|
||||
(`(object: unknown) => any`): 객체에서 주어진 경로에 있는 값을 가져오는 함수.
|
||||
|
||||
### 예시
|
||||
|
||||
```typescript
|
||||
import { property } from 'es-toolkit/compat';
|
||||
|
||||
const getObjectValue = property('a.b.c');
|
||||
const result = getObjectValue({ a: { b: { c: 3 } } });
|
||||
console.log(result); // => 3
|
||||
|
||||
const getObjectValue = property(['a', 'b', 'c']);
|
||||
const result = getObjectValue({ a: { b: { c: 3 } } });
|
||||
console.log(result); // => 3
|
||||
```
|
36
docs/reference/compat/object/property.md
Normal file
36
docs/reference/compat/object/property.md
Normal file
@ -0,0 +1,36 @@
|
||||
# property
|
||||
|
||||
::: info
|
||||
This function is fully compatible with lodash. You can find it in our [compatibility library](../../../compatibility.md), `es-toolkit/compat`.
|
||||
:::
|
||||
|
||||
Creates a function that returns the value at a given path of an object.
|
||||
It leverages the [`get`](./get.md) functions to obtain the value.
|
||||
|
||||
## Signature
|
||||
|
||||
```typescript
|
||||
function property(path: PropertyKey | readonly PropertyKey[]): (object: unknown) => any
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
||||
- `path` (`string` or `number` or `symbol` or `Array<string | number | symbol>`): The path of the property to get.
|
||||
|
||||
### Returns
|
||||
|
||||
(`(object: unknown) => any`): A new function that takes an object and returns the value at the specified path.
|
||||
|
||||
### Examples
|
||||
|
||||
```typescript
|
||||
import { property } from 'es-toolkit/compat';
|
||||
|
||||
const getObjectValue = property('a.b.c');
|
||||
const result = getObjectValue({ a: { b: { c: 3 } } });
|
||||
console.log(result); // => 3
|
||||
|
||||
const getObjectValue = property(['a', 'b', 'c']);
|
||||
const result = getObjectValue({ a: { b: { c: 3 } } });
|
||||
console.log(result); // => 3
|
||||
```
|
35
docs/zh_hans/reference/compat/object/property.md
Normal file
35
docs/zh_hans/reference/compat/object/property.md
Normal file
@ -0,0 +1,35 @@
|
||||
# property
|
||||
|
||||
::: info
|
||||
此函数与 lodash 完全兼容。您可以在我们的[兼容性库](../../../compatibility.md)中找到它,`es-toolkit/compat`。
|
||||
:::
|
||||
|
||||
`property` 函数创建一个新函数,用于从对象中获取指定路径的值。它利用 [`get`](./get.md) 函数来获取值。
|
||||
|
||||
## 签名
|
||||
|
||||
```typescript
|
||||
function property(path: PropertyKey | readonly PropertyKey[]): (object: unknown) => any
|
||||
```
|
||||
|
||||
### 参数
|
||||
|
||||
- `path` (`string` | `number` | `symbol` | `Array<string | number | symbol>`): 要获取的属性路径。
|
||||
|
||||
### 返回值
|
||||
|
||||
- `(object: unknown) => any`: 一个函数,接收一个对象并返回指定路径的值。
|
||||
|
||||
### 示例
|
||||
|
||||
```typescript
|
||||
import { property } from 'es-toolkit/compat';
|
||||
|
||||
const getObjectValue = property('a.b.c');
|
||||
const result = getObjectValue({ a: { b: { c: 3 } } });
|
||||
console.log(result); // => 3
|
||||
|
||||
const getObjectValue = property(['a', 'b', 'c']);
|
||||
const result = getObjectValue({ a: { b: { c: 3 } } });
|
||||
console.log(result); // => 3
|
||||
```
|
@ -33,6 +33,7 @@ export { head as first } from '../index.ts';
|
||||
|
||||
export { get } from './object/get.ts';
|
||||
export { set } from './object/set.ts';
|
||||
export { property } from './object/property.ts';
|
||||
|
||||
export { isPlainObject } from './predicate/isPlainObject.ts';
|
||||
export { isArray } from './predicate/isArray.ts';
|
||||
|
106
src/compat/object/property.spec.ts
Normal file
106
src/compat/object/property.spec.ts
Normal file
@ -0,0 +1,106 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { property } from './property';
|
||||
import { noop } from '../../function/noop';
|
||||
|
||||
describe('property', () => {
|
||||
it('should create a function that plucks a property value of a given object', () => {
|
||||
const object = { a: 1 };
|
||||
|
||||
['a', ['a']].forEach((path) => {
|
||||
const prop = property(path);
|
||||
expect(prop.length).toBe(1);
|
||||
expect(prop(object)).toBe(1);
|
||||
})
|
||||
});
|
||||
|
||||
it('should pluck deep property values', () => {
|
||||
const object = { a: { b: 2 } };
|
||||
|
||||
['a.b', ['a', 'b']].forEach((path) => {
|
||||
const prop = property(path);
|
||||
expect(prop(object)).toBe(2);
|
||||
});
|
||||
});
|
||||
|
||||
it('should pluck inherited property values', () => {
|
||||
function Foo() { }
|
||||
Foo.prototype.a = 1;
|
||||
|
||||
['a', ['a']].forEach((path) => {
|
||||
const prop = property(path);
|
||||
expect(prop(
|
||||
// eslint-disable-next-line
|
||||
// @ts-ignore
|
||||
new Foo()
|
||||
)).toBe(1);
|
||||
});
|
||||
});
|
||||
|
||||
it('should work with a non-string `path`', () => {
|
||||
const array = [1, 2, 3];
|
||||
|
||||
[1, [1]].forEach((path) => {
|
||||
const prop = property(path);
|
||||
expect(prop(array)).toBe(2);
|
||||
});
|
||||
});
|
||||
|
||||
it('should preserve the sign of `0`', () => {
|
||||
const object = { '-0': 'a', 0: 'b' };
|
||||
const props = [-0, Object(-0), 0, Object(0)];
|
||||
|
||||
const actual = props.map((key) => {
|
||||
const prop = property(key);
|
||||
return prop(object);
|
||||
});
|
||||
|
||||
expect(actual).toEqual(['a', 'a', 'b', 'b']);
|
||||
});
|
||||
|
||||
it('should pluck a key over a path', () => {
|
||||
const object = { 'a.b': 1, a: { b: 2 } };
|
||||
|
||||
['a.b', ['a.b']].forEach((path) => {
|
||||
const prop = property(path);
|
||||
expect(prop(object)).toBe(1);
|
||||
});
|
||||
});
|
||||
|
||||
it('should return `undefined` when `object` is nullish', () => {
|
||||
const values = [null, undefined];
|
||||
const expected = values.map(noop);
|
||||
|
||||
['constructor', ['constructor']].forEach((path) => {
|
||||
const prop = property(path);
|
||||
|
||||
const actual = values.map((value) => prop(value))
|
||||
|
||||
expect(actual).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
it('should return `undefined` for deep paths when `object` is nullish', () => {
|
||||
const values = [null, undefined];
|
||||
const expected = values.map(noop);
|
||||
|
||||
['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']]
|
||||
.forEach(
|
||||
(path) => {
|
||||
const prop = property(path);
|
||||
|
||||
const actual = values.map((value, index) => prop(value));
|
||||
|
||||
expect(actual).toEqual(expected);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
it('should return `undefined` if parts of `path` are missing', () => {
|
||||
const object = {};
|
||||
|
||||
['a', 'a[1].b.c', ['a'], ['a', '1', 'b', 'c']].forEach((path) => {
|
||||
const prop = property(path);
|
||||
expect(prop(object)).toBe(undefined);
|
||||
});
|
||||
});
|
||||
});
|
23
src/compat/object/property.ts
Normal file
23
src/compat/object/property.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { get } from "./get.ts";
|
||||
|
||||
/**
|
||||
* Creates a function that returns the value at a given path of an object.
|
||||
*
|
||||
* @param {PropertyKey | readonly PropertyKey[]} path - The path of the property to get.
|
||||
* @returns {(object: unknown) => any} - Returns a new function that takes an object and returns the value at the specified path.
|
||||
*
|
||||
* @example
|
||||
* const getObjectValue = property('a.b.c');
|
||||
* const result = getObjectValue({ a: { b: { c: 3 } } });
|
||||
* console.log(result); // => 3
|
||||
*
|
||||
* @example
|
||||
* const getObjectValue = property(['a', 'b', 'c']);
|
||||
* const result = getObjectValue({ a: { b: { c: 3 } } });
|
||||
* console.log(result); // => 3
|
||||
*/
|
||||
export function property(path: PropertyKey | readonly PropertyKey[]): (object: unknown) => any {
|
||||
return function (object: unknown) {
|
||||
return get(object, path);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user