Skip to content

Commit 8f5056b

Browse files
committed
Add getIn() method
1 parent 7492cda commit 8f5056b

File tree

5 files changed

+100
-5
lines changed

5 files changed

+100
-5
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@
77

88
## Coverage
99

10-
| Statements | Branches | Functions | Lines |
11-
| --- | --- | --- | --- |
12-
| ![Statements](https://img.shields.io/badge/Coverage-100%25-brightgreen.svg) | ![Branches](https://img.shields.io/badge/Coverage-93.33%25-brightgreen.svg) | ![Functions](https://img.shields.io/badge/Coverage-100%25-brightgreen.svg) | ![Lines](https://img.shields.io/badge/Coverage-100%25-brightgreen.svg) |
10+
| Statements | Branches | Functions | Lines |
11+
| --------------------------------------------------------------------------- | --------------------------------------------------------------------------- | -------------------------------------------------------------------------- | ---------------------------------------------------------------------- |
12+
| ![Statements](https://img.shields.io/badge/Coverage-100%25-brightgreen.svg) | ![Branches](https://img.shields.io/badge/Coverage-95.24%25-brightgreen.svg) | ![Functions](https://img.shields.io/badge/Coverage-100%25-brightgreen.svg) | ![Lines](https://img.shields.io/badge/Coverage-100%25-brightgreen.svg) |

src/get-in.test.ts

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// -----------------------------------------------------------------------------
2+
// Deps
3+
// -----------------------------------------------------------------------------
4+
5+
import { getIn } from './get-in';
6+
7+
// -----------------------------------------------------------------------------
8+
// Tests
9+
// -----------------------------------------------------------------------------
10+
11+
const testCases: {
12+
parameters: Parameters<typeof getIn>;
13+
result: ReturnType<typeof getIn>;
14+
}[] = [
15+
{
16+
parameters: [{ key: 'value' }, 'key'],
17+
result: 'value'
18+
},
19+
{
20+
parameters: [{ key: 'value' }, 'ZZZ'],
21+
result: undefined
22+
},
23+
{
24+
parameters: [
25+
{
26+
key1: {
27+
key2: {
28+
key3: 'value'
29+
}
30+
}
31+
},
32+
'key1.key2.key3'
33+
],
34+
result: 'value'
35+
},
36+
{
37+
parameters: [
38+
{
39+
key1: ['value0', 'value1', 'value2']
40+
},
41+
'key1[1]'
42+
],
43+
result: 'value1'
44+
},
45+
{
46+
parameters: [['value0', 'value1', 'value2'], '[1]'],
47+
result: 'value1'
48+
}
49+
];
50+
51+
describe('getIn tool', () => {
52+
testCases.forEach(({ parameters, result }, i) => {
53+
test(`test #${i + 1}: ${parameters.join(', ')}`, () => {
54+
const value = getIn(...parameters);
55+
expect(value).toStrictEqual(result);
56+
});
57+
});
58+
});

src/get-in.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// -----------------------------------------------------------------------------
2+
// Deps
3+
// -----------------------------------------------------------------------------
4+
5+
import { IPlainObject } from './types';
6+
import { toPath } from './to-path';
7+
import { isPlainObject } from './is-plain-object';
8+
9+
/**
10+
* Convert string sample in to the path (array)
11+
* Inspired by final-form's `toPath` helper
12+
* {@link https://github.com/final-form/final-form/blob/master/src/structure/toPath.js}
13+
* @param {IPlainObject|Array} sample
14+
* @param {string} keyPath
15+
*/
16+
export function getIn<GValue = any>(
17+
sample: IPlainObject | GValue[],
18+
keyPath: string
19+
): GValue | undefined {
20+
const path = toPath(keyPath);
21+
const pathLength = path.length;
22+
23+
let current: any = sample;
24+
for (let i = 0; i < pathLength; i++) {
25+
const key: string = path[i];
26+
if (
27+
(isPlainObject(current) && current.hasOwnProperty(key)) ||
28+
(Array.isArray(current) && !isNaN(+key))
29+
) {
30+
current = current[key];
31+
} else {
32+
current = undefined;
33+
break;
34+
}
35+
}
36+
return current;
37+
}

src/to-path.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Deps
33
// -----------------------------------------------------------------------------
44

5-
import toPath from './to-path';
5+
import { toPath } from './to-path';
66

77
// -----------------------------------------------------------------------------
88
// Tests

src/to-path.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ const regex = /(\[(?=\d+])|(?<=\[\d+)])|\.+/;
88
* @param {string|null} [sample]
99
* @returns {string[]}
1010
*/
11-
export default (sample?: string | null): string[] => {
11+
export const toPath = (sample?: string | null): string[] => {
1212
if (typeof sample === 'string' && sample.length > 0 && sample !== 'hasOwnProperty') {
1313
if (!cache.hasOwnProperty(sample)) {
1414
cache[sample] = sample

0 commit comments

Comments
 (0)