From 0d6bd794759a7517a5ea63d77c8d5123d13fbe59 Mon Sep 17 00:00:00 2001 From: DomiR Date: Fri, 15 Jan 2016 11:52:01 +0100 Subject: [PATCH] (feature) Add _.mergeWith --- lodash/lodash-tests.ts | 84 +++++++-------- lodash/lodash.d.ts | 228 +++++++++++++++++++++++++++++++---------- 2 files changed, 213 insertions(+), 99 deletions(-) diff --git a/lodash/lodash-tests.ts b/lodash/lodash-tests.ts index 2e95b756d..b43e4eb3c 100644 --- a/lodash/lodash-tests.ts +++ b/lodash/lodash-tests.ts @@ -8421,32 +8421,19 @@ module TestMerge { type ExpectedResult = { a: number, b: string }; let result: ExpectedResult; - let customizer: (value: any, srcValue: any, key?: string, object?: InitialValue, source?: MergingValue) => any; - // Test for basic merging result = _.merge(initialValue, mergingValue); - result = _.merge(initialValue, mergingValue, customizer); - result = _.merge(initialValue, mergingValue, customizer, any); result = _.merge(initialValue, {}, mergingValue); - result = _.merge(initialValue, {}, mergingValue, customizer); - result = _.merge(initialValue, {}, mergingValue, customizer, any); result = _.merge(initialValue, {}, {}, mergingValue); - result = _.merge(initialValue, {}, {}, mergingValue, customizer); - result = _.merge(initialValue, {}, {}, mergingValue, customizer, any); result = _.merge(initialValue, {}, {}, {}, mergingValue); - result = _.merge(initialValue, {}, {}, {}, mergingValue, customizer); - result = _.merge(initialValue, {}, {}, {}, mergingValue, customizer, any); // Once we get to the varargs version, you have to specify the result explicitly result = _.merge(initialValue, {}, {}, {}, {}, mergingValue); - result = _.merge(initialValue, {}, {}, {}, {}, mergingValue, customizer); - result = _.merge(initialValue, {}, {}, {}, {}, mergingValue, customizer, any); - // Test for multiple combinations of many types type ComplicatedExpectedType = { a: number, b: string, c: {}, d: number[], e: boolean }; @@ -8468,25 +8455,15 @@ module TestMerge { // Tests for basic chaining with merge result = _(initialValue).merge(mergingValue).value(); - result = _(initialValue).merge(mergingValue, customizer).value(); - result = _(initialValue).merge(mergingValue, customizer, any).value(); result = _(initialValue).merge({}, mergingValue).value(); - result = _(initialValue).merge({}, mergingValue, customizer).value(); - result = _(initialValue).merge({}, mergingValue, customizer, any).value(); result = _(initialValue).merge({}, {}, mergingValue).value(); - result = _(initialValue).merge({}, {}, mergingValue, customizer).value(); - result = _(initialValue).merge({}, {}, mergingValue, customizer, any).value(); result = _(initialValue).merge({}, {}, {}, mergingValue).value(); - result = _(initialValue).merge({}, {}, {}, mergingValue, customizer).value(); - result = _(initialValue).merge({}, {}, {}, mergingValue, customizer, any).value(); // Once we get to the varargs version, you have to specify the result explicitly result = _(initialValue).merge({}, {}, {}, {}, mergingValue).value(); - result = _(initialValue).merge({}, {}, {}, {}, mergingValue, customizer).value(); - result = _(initialValue).merge({}, {}, {}, {}, mergingValue, customizer, any).value(); // Test complex multiple combinations with chaining @@ -8504,41 +8481,58 @@ module TestMerge { { let result: _.LoDashExplicitObjectWrapper; - - result = _(initialValue).chain().merge(mergingValue); - result = _(initialValue).chain().merge(mergingValue, customizer); - result = _(initialValue).chain().merge(mergingValue, customizer, any); - - result = _(initialValue).chain().merge({}, mergingValue); - result = _(initialValue).chain().merge({}, mergingValue, customizer); - result = _(initialValue).chain().merge({}, mergingValue, customizer, any); - - result = _(initialValue).chain().merge({}, {}, mergingValue); - result = _(initialValue).chain().merge({}, {}, mergingValue, customizer); - result = _(initialValue).chain().merge({}, {}, mergingValue, customizer, any); - - result = _(initialValue).chain().merge({}, {}, {}, mergingValue); - result = _(initialValue).chain().merge({}, {}, {}, mergingValue, customizer); - result = _(initialValue).chain().merge({}, {}, {}, mergingValue, customizer, any); - - result = _(initialValue).chain().merge({}, {}, {}, {}, mergingValue); - result = _(initialValue).chain().merge({}, {}, {}, {}, mergingValue, customizer); - result = _(initialValue).chain().merge({}, {}, {}, {}, mergingValue, customizer, any); + // result = _(initialValue).chain().merge(mergingValue); + // result = _(initialValue).chain().merge({}, mergingValue); + // result = _(initialValue).chain().merge({}, {}, mergingValue); + // result = _(initialValue).chain().merge({}, {}, {}, mergingValue); + // result = _(initialValue).chain().merge({}, {}, {}, {}, mergingValue); } { let result: _.LoDashExplicitObjectWrapper; - result = _({ a: 1 }).chain().merge({ b: "string" }, { c: {} }, { d: [1] }, { e: true }); + //result = _({ a: 1 }).chain().merge({ b: "string" }, { c: {} }, { d: [1] }, { e: true }); } { let result: _.LoDashExplicitObjectWrapper; - result = _({ a: 1 }).chain().merge({ a: "string" }, { a: {} }, { a: [1] }, { a: true }); + //result = _({ a: 1 }).chain().merge({ a: "string" }, { a: {} }, { a: [1] }, { a: true }); } } +// _.mergeWith +module TestMergeWith { + type InitialValue = { a : number }; + type MergingValue = { b : string }; + + var initialValue = { a : 1 }; + var mergingValue = { b : "hi" }; + + type ExpectedResult = { a: number, b: string }; + let result: ExpectedResult; + + let customizer: (value: any, srcValue: any, key?: string, object?: InitialValue, source?: MergingValue) => any; + + // Test for basic merging + result = _.mergeWith(initialValue, mergingValue, customizer); + result = _.mergeWith(initialValue, {}, mergingValue, customizer); + result = _.mergeWith(initialValue, {}, {}, mergingValue, customizer); + result = _.mergeWith(initialValue, {}, {}, {}, mergingValue, customizer); + + // Once we get to the varargs version, you have to specify the result explicitl + result = _.mergeWith(initialValue, {}, {}, {}, {}, mergingValue, customizer); + + // Tests for basic chaining with mergeWith + result = _(initialValue).mergeWith(mergingValue, customizer).value(); + result = _(initialValue).mergeWith({}, mergingValue, customizer).value(); + result = _(initialValue).mergeWith({}, {}, mergingValue, customizer).value(); + result = _(initialValue).mergeWith({}, {}, {}, mergingValue, customizer).value(); + + // Once we get to the varargs version, you have to specify the result explicitl + result = _(initialValue).mergeWith({}, {}, {}, {}, mergingValue, customizer).value(); +} + // _.omit module TestOmit { let predicate: (element: any, key: string, collection: any) => boolean; diff --git a/lodash/lodash.d.ts b/lodash/lodash.d.ts index 14b0f7246..6126d16e7 100644 --- a/lodash/lodash.d.ts +++ b/lodash/lodash.d.ts @@ -105,7 +105,7 @@ added 13 object methods: - [x] _.functionsIn - [x] _.hasIn - [ ] _.invoke -- [ ] _.mergeWith +- [x] _.mergeWith - [x] _.omitBy - [x] _.pickBy - [ ] _.setWith @@ -13500,29 +13500,39 @@ declare module _ { } //_.merge - interface MergeCustomizer { - (value: any, srcValue: any, key?: string, object?: Object, source?: Object): any; - } - interface LoDashStatic { /** - * Recursively merges own enumerable properties of the source object(s), that don’t resolve to undefined into - * the destination object. Subsequent sources overwrite property assignments of previous sources. If customizer - * is provided it’s invoked to produce the merged values of the destination and source properties. If - * customizer returns undefined merging is handled by the method instead. The customizer is bound to thisArg - * and invoked with five arguments: (objectValue, sourceValue, key, object, source). + * Recursively merges own and inherited enumerable properties of source + * objects into the destination object, skipping source properties that resolve + * to `undefined`. Array and plain object properties are merged recursively. + * Other objects and value types are overridden by assignment. Source objects + * are applied from left to right. Subsequent sources overwrite property + * assignments of previous sources. * - * @param object The destination object. - * @param source The source objects. - * @param customizer The function to customize assigned values. - * @param thisArg The this binding of customizer. - * @return Returns object. + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @example + * + * var users = { + * 'data': [{ 'user': 'barney' }, { 'user': 'fred' }] + * }; + * + * var ages = { + * 'data': [{ 'age': 36 }, { 'age': 40 }] + * }; + * + * _.merge(users, ages); + * // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] } */ merge( object: TObject, - source: TSource, - customizer?: MergeCustomizer, - thisArg?: any + source: TSource ): TObject & TSource; /** @@ -13531,9 +13541,7 @@ declare module _ { merge( object: TObject, source1: TSource1, - source2: TSource2, - customizer?: MergeCustomizer, - thisArg?: any + source2: TSource2 ): TObject & TSource1 & TSource2; /** @@ -13543,9 +13551,7 @@ declare module _ { object: TObject, source1: TSource1, source2: TSource2, - source3: TSource3, - customizer?: MergeCustomizer, - thisArg?: any + source3: TSource3 ): TObject & TSource1 & TSource2 & TSource3; /** @@ -13556,9 +13562,7 @@ declare module _ { source1: TSource1, source2: TSource2, source3: TSource3, - source4: TSource4, - customizer?: MergeCustomizer, - thisArg?: any + source4: TSource4 ): TObject & TSource1 & TSource2 & TSource3 & TSource4; /** @@ -13575,9 +13579,7 @@ declare module _ { * @see _.merge */ merge( - source: TSource, - customizer?: MergeCustomizer, - thisArg?: any + source: TSource ): LoDashImplicitObjectWrapper; /** @@ -13585,9 +13587,7 @@ declare module _ { */ merge( source1: TSource1, - source2: TSource2, - customizer?: MergeCustomizer, - thisArg?: any + source2: TSource2 ): LoDashImplicitObjectWrapper; /** @@ -13596,9 +13596,7 @@ declare module _ { merge( source1: TSource1, source2: TSource2, - source3: TSource3, - customizer?: MergeCustomizer, - thisArg?: any + source3: TSource3 ): LoDashImplicitObjectWrapper; /** @@ -13608,9 +13606,7 @@ declare module _ { source1: TSource1, source2: TSource2, source3: TSource3, - source4: TSource4, - customizer?: MergeCustomizer, - thisArg?: any + source4: TSource4 ): LoDashImplicitObjectWrapper; /** @@ -13626,9 +13622,7 @@ declare module _ { * @see _.merge */ merge( - source: TSource, - customizer?: MergeCustomizer, - thisArg?: any + source: TSource ): LoDashExplicitObjectWrapper; /** @@ -13636,9 +13630,7 @@ declare module _ { */ merge( source1: TSource1, - source2: TSource2, - customizer?: MergeCustomizer, - thisArg?: any + source2: TSource2 ): LoDashExplicitObjectWrapper; /** @@ -13647,21 +13639,13 @@ declare module _ { merge( source1: TSource1, source2: TSource2, - source3: TSource3, - customizer?: MergeCustomizer, - thisArg?: any + source3: TSource3 ): LoDashExplicitObjectWrapper; /** * @see _.merge */ merge( - source1: TSource1, - source2: TSource2, - source3: TSource3, - source4: TSource4, - customizer?: MergeCustomizer, - thisArg?: any ): LoDashExplicitObjectWrapper; /** @@ -13672,6 +13656,142 @@ declare module _ { ): LoDashExplicitObjectWrapper; } + //_.mergeWith + interface MergeWithCustomizer { + (value: any, srcValue: any, key?: string, object?: Object, source?: Object): any; + } + + interface LoDashStatic { + /** + * This method is like `_.merge` except that it accepts `customizer` which + * is invoked to produce the merged values of the destination and source + * properties. If `customizer` returns `undefined` merging is handled by the + * method instead. The `customizer` is invoked with seven arguments: + * (objValue, srcValue, key, object, source, stack). + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} sources The source objects. + * @param {Function} customizer The function to customize assigned values. + * @returns {Object} Returns `object`. + * @example + * + * function customizer(objValue, srcValue) { + * if (_.isArray(objValue)) { + * return objValue.concat(srcValue); + * } + * } + * + * var object = { + * 'fruits': ['apple'], + * 'vegetables': ['beet'] + * }; + * + * var other = { + * 'fruits': ['banana'], + * 'vegetables': ['carrot'] + * }; + * + * _.merge(object, other, customizer); + * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] } + */ + mergeWith( + object: TObject, + source: TSource, + customizer: MergeWithCustomizer + ): TObject & TSource; + + /** + * @see _.mergeWith + */ + mergeWith( + object: TObject, + source1: TSource1, + source2: TSource2, + customizer: MergeWithCustomizer + ): TObject & TSource1 & TSource2; + + /** + * @see _.mergeWith + */ + mergeWith( + object: TObject, + source1: TSource1, + source2: TSource2, + source3: TSource3, + customizer: MergeWithCustomizer + ): TObject & TSource1 & TSource2 & TSource3; + + /** + * @see _.mergeWith + */ + mergeWith( + object: TObject, + source1: TSource1, + source2: TSource2, + source3: TSource3, + source4: TSource4, + customizer: MergeWithCustomizer + ): TObject & TSource1 & TSource2 & TSource3 & TSource4; + + /** + * @see _.mergeWith + */ + mergeWith( + object: any, + ...otherArgs: any[] + ): TResult; + } + + interface LoDashImplicitObjectWrapper { + /** + * @see _.mergeWith + */ + mergeWith( + source: TSource, + customizer: MergeWithCustomizer + ): LoDashImplicitObjectWrapper; + + /** + * @see _.mergeWith + */ + mergeWith( + source1: TSource1, + source2: TSource2, + customizer: MergeWithCustomizer + ): LoDashImplicitObjectWrapper; + + /** + * @see _.mergeWith + */ + mergeWith( + source1: TSource1, + source2: TSource2, + source3: TSource3, + customizer: MergeWithCustomizer + ): LoDashImplicitObjectWrapper; + + /** + * @see _.mergeWith + */ + mergeWith( + source1: TSource1, + source2: TSource2, + source3: TSource3, + source4: TSource4, + customizer: MergeWithCustomizer + ): LoDashImplicitObjectWrapper; + + /** + * @see _.mergeWith + */ + mergeWith( + ...otherArgs: any[] + ): LoDashImplicitObjectWrapper; + } + //_.omit interface LoDashStatic { /**