Skip to content

Commit

Permalink
feat: 新增 deepMerge 题目
Browse files Browse the repository at this point in the history
  • Loading branch information
xjq7 committed Nov 19, 2022
1 parent 8cfcb18 commit f4bb928
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 1 deletion.
37 changes: 37 additions & 0 deletions question/FrontEnd/deepMerge/answer.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
function getType(o) {
return Object.prototype.toString.call(o);
}

function deepClone(obj, weakMap = new WeakMap()) {
const type = Object.prototype.toString.call(obj);
if (!(type === '[object Object]' || type === '[object Array]')) return obj;
const o = type === '[object Object]' ? {} : [];
if (weakMap.get(obj)) return o;
weakMap.set(obj, true);
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
o[key] = deepClone(obj[key], weakMap);
}
}
return o;
}

export default function deepMerge(a, b) {
if (getType(a) !== '[object Object]' && getType(a) !== '[object Array]') {
return deepClone(b);
}

const isArray = getType(a) === '[object Array]';
const res = isArray ? [] : {};
for (const key in b) {
if (b.hasOwnProperty(key)) {
res[key] = deepMerge(a[key], b[key]);
}
}
for (const key in a) {
if (res[key] === undefined && a.hasOwnProperty(key)) {
res[key] = deepClone(a[key]);
}
}
return res;
}
50 changes: 50 additions & 0 deletions question/FrontEnd/deepMerge/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
对象合并

深度合并两个对象, 并且修改新对象不会影响原对象, 相同的属性则以 b 对象为主

用例 1:

```js
const a = { a: 1 };
const b = { b: 2 };

deepMerge(a, b); // { a: 1, b: 2 }
```

用例 2:

```js
const a = { foo: { bar: 0 }, arr: [1, 3, { a: { b: 1 } }] };
const b = { foo: { bar: 1 }, arr: [1, 2, { b: { a: 1 } }] };

deepMerge(a, b); // { foo: { bar: 1 }, arr: [1, 2, { a: { b: 1 }, b: { a: 1 } }] }
```

用例 3:

b 属性值为 undefined 不会并入 a

```js
const a = { a: 1 };
const b = { a: undefined };

deepMerge(a, b); // { a: 1 }
```

用例 4:

```js
const a = { a: 1 };
const b = undefined;

deepMerge(a, b); // { a: 1 }
```

用例 5:

```js
const a = undefined;
const b = { a: 1 };

deepMerge(a, b); // { a: 1 }
```
11 changes: 11 additions & 0 deletions question/FrontEnd/deepMerge/index.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/**
* 对象合并
*
* @export
* @param {Object} a
* @param {Object} b
* @return {Object}
*/
export default function deepMerge(a, b) {
return {};
}
35 changes: 35 additions & 0 deletions question/FrontEnd/deepMerge/test.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import f from './index.mjs';
import { it } from 'mocha';
import { assert } from 'chai';

it('一层对象: 输入 { a: 1 }, { b: 2 }', () => {
assert.deepEqual(f({ a: 1 }, { b: 2 }), { a: 1, b: 2 });
});

it('两层对象: 输入 { a: 1, b: { c: 2 } }, { b: 2 }', () => {
assert.deepEqual(f({ a: 1, b: { c: 2 } }, { b: { c: 3, d: 4 } }), {
a: 1,
b: { c: 3, d: 4 },
});
});

it("两层对象存在数组合并: 输入 { b: { c: [1, 3, { a: 1 }] } }, { b: { c: ['1', 2, { a: 2 }] } }", () => {
assert.deepEqual(
f({ b: { c: [1, 3, { a: 1 }] } }, { b: { c: ['1', 2, { a: 2 }] } }),
{ b: { c: ['1', 2, { a: 2 }] } }
);
});

it('b 中属性值为 undefined 时不会合并: 输入 { a: 1 }, { a: undefined }', () => {
assert.deepEqual(f({ a: 1 }, { a: undefined }), { a: 1 });
});

it('边界输入一 undefined | null, { a: 1 }', () => {
assert.deepEqual(f(undefined, { a: 1 }), { a: 1 });
assert.deepEqual(f(null, { a: 1 }), { a: 1 });
});

it('边界输入二 { a: 1 }, undefined | null', () => {
assert.deepEqual(f({ a: 1 }, undefined), { a: 1 });
assert.deepEqual(f({ a: 1 }, null), { a: 1 });
});
2 changes: 1 addition & 1 deletion server/src/qsdata/questions.json

Large diffs are not rendered by default.

0 comments on commit f4bb928

Please sign in to comment.