Skip to content

Commit e5063bc

Browse files
committed
refactor: replace mergeConfigProperty with mergeArraysBy utils function
- Refactored `mergeConfigProperty` into a new generic `mergeArraysBy` utility function. - Removed `mergeConfigProperty` method from `Configuration` class. - Added new `mergeArraysBy` utility function in `utils` file, and updated the code to be more generic with better typings. - Replaced all references to the old method in `Configuration` with the new utils function.
1 parent e6214cd commit e5063bc

2 files changed

Lines changed: 48 additions & 43 deletions

File tree

src/configuration.ts

Lines changed: 5 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -700,14 +700,10 @@ export class Configuration {
700700
let langConfig = {...internalLangConfig};
701701

702702
if (multiLine) {
703-
langConfig.autoClosingPairs = this.mergeConfigProperty(
704-
defaultMultiLineConfig.autoClosingPairs,
705-
internalLangConfig?.autoClosingPairs,
706-
"open"
707-
);
703+
langConfig.autoClosingPairs = utils.mergeArraysBy(defaultMultiLineConfig.autoClosingPairs, internalLangConfig?.autoClosingPairs, "open");
708704

709705
// Add the multi-line onEnter rules to the langConfig.
710-
langConfig.onEnterRules = this.mergeConfigProperty(Rules.multilineEnterRules, internalLangConfig?.onEnterRules, "beforeText");
706+
langConfig.onEnterRules = utils.mergeArraysBy(Rules.multilineEnterRules, internalLangConfig?.onEnterRules, "beforeText");
711707

712708
// Only assign the default config comments if it doesn't already exist.
713709
// (nullish assignment operator ??=)
@@ -736,15 +732,15 @@ export class Configuration {
736732
if (isOnEnter && singleLineStyle) {
737733
// //-style comments
738734
if (singleLineStyle === "//") {
739-
langConfig.onEnterRules = this.mergeConfigProperty(Rules.slashEnterRules, langConfig?.onEnterRules, "beforeText");
735+
langConfig.onEnterRules = utils.mergeArraysBy(Rules.slashEnterRules, langConfig?.onEnterRules, "beforeText");
740736
}
741737
// #-style comments
742738
else if (singleLineStyle === "#") {
743-
langConfig.onEnterRules = this.mergeConfigProperty(Rules.hashEnterRules, langConfig?.onEnterRules, "beforeText");
739+
langConfig.onEnterRules = utils.mergeArraysBy(Rules.hashEnterRules, langConfig?.onEnterRules, "beforeText");
744740
}
745741
// ;-style comments
746742
else if (singleLineStyle === ";") {
747-
langConfig.onEnterRules = this.mergeConfigProperty(Rules.semicolonEnterRules, langConfig?.onEnterRules, "beforeText");
743+
langConfig.onEnterRules = utils.mergeArraysBy(Rules.semicolonEnterRules, langConfig?.onEnterRules, "beforeText");
748744
}
749745
}
750746
// If isOnEnter is false AND singleLineStyle isn't false, i.e. a string.
@@ -854,40 +850,6 @@ export class Configuration {
854850
return vscode.languages.setLanguageConfiguration(langId, langConfig);
855851
}
856852

857-
/**
858-
* Merges two configuration properties arrays, removing any duplicates based on a
859-
* specified property.
860-
*
861-
* @param {any[]} defaultConfigProperty The default configuration property array of objects.
862-
* @param {any[]} internalConfigProperty The internal configuration property array of objects.
863-
* @param {string} objectKey The key within the array item object to check against for preventing duplicates
864-
* @returns {any[]} The merged configuration property array without duplicates.
865-
*/
866-
private mergeConfigProperty(defaultConfigProperty: any[], internalConfigProperty: any[], objectKey: string) {
867-
// Define an empty array if the internalConfigProperty is undefined.
868-
internalConfigProperty ??= [];
869-
870-
// Copy to avoid side effects.
871-
const merged = [...defaultConfigProperty];
872-
873-
/**
874-
* Merge the arrays and remove any duplicates.
875-
*/
876-
877-
// Loop over the internalConfigProperty array...
878-
internalConfigProperty.forEach((item) =>
879-
// Test all items in the merged array, and if the item's
880-
// key is not already present in one of the merged array's objects then add the item
881-
// to the merged array.
882-
//
883-
// Code based on "2023 update" portion of this StackOverflow answer:
884-
// https://stackoverflow.com/a/1584377/2358222
885-
merged.some((mergedItem) => item[objectKey] === mergedItem[objectKey]) ? null : merged.push(item)
886-
);
887-
888-
return merged;
889-
}
890-
891853
/**
892854
* The keyboard binding event handler for the single-line blocks on shift+enter.
893855
*

src/utils.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,3 +125,46 @@ export function convertMapToReversedObject(m: Map<string, Map<string, string>>):
125125
}
126126
return result;
127127
}
128+
129+
/**
130+
* Merges two arrays of objects, removing duplicates based on a specified property.
131+
*
132+
* Code based on "2023 update" portion of this StackOverflow answer:
133+
* https://stackoverflow.com/a/1584377/2358222
134+
*
135+
* @param {T[]} primaryArray The primary array of objects (takes precedence).
136+
* @param {T[]} secondaryArray The secondary array of objects to merge in.
137+
* @param {keyof T} key The property key to check for duplicates.
138+
*
139+
* @returns {T[]} The merged array without duplicates
140+
*
141+
* @example
142+
* const users1 = [{id: 1, name: 'John'}, {id: 2, name: 'Jane'}];
143+
* const users2 = [{id: 2, name: 'Jane'}, {id: 3, name: 'Jane Doe'}];
144+
* const merged = mergeArraysBy(users1, users2, 'name');
145+
* // Result: [{id: 1, name: 'John'}, {id: 2, name: 'Jane'}, {id: 3, name: 'Jane Doe'}]
146+
*/
147+
export function mergeArraysBy<T>(primaryArray: T[], secondaryArray: T[], key: keyof T): T[] {
148+
// Handle undefined/null arrays
149+
const primary = primaryArray || [];
150+
const secondary = secondaryArray || [];
151+
152+
// Start with primary array (avoids side effects)
153+
const merged = [...primary];
154+
155+
// Add items from secondary array that don't exist in primary,
156+
// removing any duplicates.
157+
secondary.forEach((item) => {
158+
// Test all items in the merged array to check if the value of the key
159+
// already exists in the merged array.
160+
const exists: boolean = merged.some((existingItem) => item[key] === existingItem[key]);
161+
162+
// If the value of the key does not exist in the merged array,
163+
// then add the item, which prevents duplicates.
164+
if (!exists) {
165+
merged.push(item);
166+
}
167+
});
168+
169+
return merged;
170+
}

0 commit comments

Comments
 (0)