MOBILE-4565 utils: Move some array functions to CoreArray
parent
f9ddfb48c9
commit
93b420311d
|
@ -28,6 +28,7 @@ import { CoreDomUtils } from '@services/utils/dom';
|
||||||
import { CoreTextUtils } from '@services/utils/text';
|
import { CoreTextUtils } from '@services/utils/text';
|
||||||
import { CoreUrlUtils } from '@services/utils/url';
|
import { CoreUrlUtils } from '@services/utils/url';
|
||||||
import { CoreUtils } from '@services/utils/utils';
|
import { CoreUtils } from '@services/utils/utils';
|
||||||
|
import { CoreArray } from '@singletons/array';
|
||||||
import { CoreEventObserver, CoreEvents } from '@singletons/events';
|
import { CoreEventObserver, CoreEvents } from '@singletons/events';
|
||||||
import { CoreTime } from '@singletons/time';
|
import { CoreTime } from '@singletons/time';
|
||||||
|
|
||||||
|
@ -218,7 +219,7 @@ export class AddonBlogIndexPage implements OnInit, OnDestroy {
|
||||||
if (refresh) {
|
if (refresh) {
|
||||||
this.entries = result.entries;
|
this.entries = result.entries;
|
||||||
} else {
|
} else {
|
||||||
this.entries = CoreUtils.uniqueArray(this.entries
|
this.entries = CoreArray.unique(this.entries
|
||||||
.concat(result.entries), 'id')
|
.concat(result.entries), 'id')
|
||||||
.sort((a, b) => b.created - a.created);
|
.sort((a, b) => b.created - a.created);
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,7 @@ import { CoreTextUtils } from '@services/utils/text';
|
||||||
import { CoreXAPIIRI } from '@features/xapi/classes/iri';
|
import { CoreXAPIIRI } from '@features/xapi/classes/iri';
|
||||||
import { CoreXAPIItemAgent } from '@features/xapi/classes/item-agent';
|
import { CoreXAPIItemAgent } from '@features/xapi/classes/item-agent';
|
||||||
import { CoreWSError } from '@classes/errors/wserror';
|
import { CoreWSError } from '@classes/errors/wserror';
|
||||||
|
import { CoreArray } from '@singletons/array';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service to sync H5P activities.
|
* Service to sync H5P activities.
|
||||||
|
@ -76,7 +77,7 @@ export class AddonModH5PActivitySyncProvider extends CoreCourseActivitySyncBaseP
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const entries = (<(CoreXAPIStatementDBRecord|CoreXAPIStateDBRecord)[]> statements).concat(states);
|
const entries = (<(CoreXAPIStatementDBRecord|CoreXAPIStateDBRecord)[]> statements).concat(states);
|
||||||
const contextIds = CoreUtils.uniqueArray(entries.map(entry => 'contextid' in entry ? entry.contextid : entry.itemid));
|
const contextIds = CoreArray.unique(entries.map(entry => 'contextid' in entry ? entry.contextid : entry.itemid));
|
||||||
|
|
||||||
// Sync all activities.
|
// Sync all activities.
|
||||||
const promises = contextIds.map(async (contextId) => {
|
const promises = contextIds.map(async (contextId) => {
|
||||||
|
|
|
@ -24,6 +24,7 @@ import { CoreEvents } from '@singletons/events';
|
||||||
import { AddonNotesDBRecord, AddonNotesDeletedDBRecord } from './database/notes';
|
import { AddonNotesDBRecord, AddonNotesDeletedDBRecord } from './database/notes';
|
||||||
import { AddonNotes, AddonNotesCreateNoteData } from './notes';
|
import { AddonNotes, AddonNotesCreateNoteData } from './notes';
|
||||||
import { AddonNotesOffline } from './notes-offline';
|
import { AddonNotesOffline } from './notes-offline';
|
||||||
|
import { CoreArray } from '@singletons/array';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service to sync notes.
|
* Service to sync notes.
|
||||||
|
@ -67,7 +68,7 @@ export class AddonNotesSyncProvider extends CoreSyncBaseProvider<AddonNotesSyncR
|
||||||
courseIds = courseIds.concat(notes.map((note) => note.courseid));
|
courseIds = courseIds.concat(notes.map((note) => note.courseid));
|
||||||
});
|
});
|
||||||
|
|
||||||
CoreUtils.uniqueArray(courseIds);
|
CoreArray.unique(courseIds);
|
||||||
|
|
||||||
// Sync all courses.
|
// Sync all courses.
|
||||||
const promises = courseIds.map(async (courseId) => {
|
const promises = courseIds.map(async (courseId) => {
|
||||||
|
|
|
@ -40,6 +40,7 @@ import { CoreDirectivesRegistry } from '@singletons/directives-registry';
|
||||||
import { CorePromisedValue } from '@classes/promised-value';
|
import { CorePromisedValue } from '@classes/promised-value';
|
||||||
import { CorePlatform } from '@services/platform';
|
import { CorePlatform } from '@services/platform';
|
||||||
import { CoreTextUtils } from '@services/utils/text';
|
import { CoreTextUtils } from '@services/utils/text';
|
||||||
|
import { CoreArray } from '@singletons/array';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Directive to handle external content.
|
* Directive to handle external content.
|
||||||
|
@ -279,7 +280,7 @@ export class CoreExternalContentDirective implements AfterViewInit, OnChanges, O
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const urls = CoreUtils.uniqueArray(Array.from(inlineStyles.match(/https?:\/\/[^"') ;]*/g) ?? []));
|
const urls = CoreArray.unique(Array.from(inlineStyles.match(/https?:\/\/[^"') ;]*/g) ?? []));
|
||||||
if (!urls.length) {
|
if (!urls.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ import { makeSingleton } from '@singletons';
|
||||||
import { CoreEnrolAction, CoreEnrolDelegate, CoreEnrolInfoIcon } from './enrol-delegate';
|
import { CoreEnrolAction, CoreEnrolDelegate, CoreEnrolInfoIcon } from './enrol-delegate';
|
||||||
import { CoreUtils } from '@services/utils/utils';
|
import { CoreUtils } from '@services/utils/utils';
|
||||||
import { CoreEnrol, CoreEnrolEnrolmentMethod } from './enrol';
|
import { CoreEnrol, CoreEnrolEnrolmentMethod } from './enrol';
|
||||||
|
import { CoreArray } from '@singletons/array';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service that provides helper functions for enrolment plugins.
|
* Service that provides helper functions for enrolment plugins.
|
||||||
|
@ -32,7 +33,7 @@ export class CoreEnrolHelperService {
|
||||||
* @returns Enrolment icons to show.
|
* @returns Enrolment icons to show.
|
||||||
*/
|
*/
|
||||||
async getEnrolmentIcons(methodTypes: string[], courseId: number): Promise<CoreEnrolInfoIcon[]> {
|
async getEnrolmentIcons(methodTypes: string[], courseId: number): Promise<CoreEnrolInfoIcon[]> {
|
||||||
methodTypes = CoreUtils.uniqueArray(methodTypes);
|
methodTypes = CoreArray.unique(methodTypes);
|
||||||
|
|
||||||
let enrolmentIcons: CoreEnrolInfoIcon[] = [];
|
let enrolmentIcons: CoreEnrolInfoIcon[] = [];
|
||||||
let addBrowserOption = false;
|
let addBrowserOption = false;
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
import { CorePlatform } from '@services/platform';
|
import { CorePlatform } from '@services/platform';
|
||||||
import { CoreUtils } from '@services/utils/utils';
|
import { CoreArray } from '@singletons/array';
|
||||||
import { makeSingleton } from '@singletons';
|
import { makeSingleton } from '@singletons';
|
||||||
import { CoreFileUploaderHandler, CoreFileUploaderHandlerData, CoreFileUploaderHandlerResult } from '../fileuploader-delegate';
|
import { CoreFileUploaderHandler, CoreFileUploaderHandlerData, CoreFileUploaderHandlerResult } from '../fileuploader-delegate';
|
||||||
import { CoreFileUploaderHelper } from '../fileuploader-helper';
|
import { CoreFileUploaderHelper } from '../fileuploader-helper';
|
||||||
|
@ -41,7 +41,7 @@ export class CoreFileUploaderAlbumHandlerService implements CoreFileUploaderHand
|
||||||
*/
|
*/
|
||||||
getSupportedMimetypes(mimetypes: string[]): string[] {
|
getSupportedMimetypes(mimetypes: string[]): string[] {
|
||||||
// Album allows picking images and videos.
|
// Album allows picking images and videos.
|
||||||
return CoreUtils.filterByRegexp(mimetypes, /^(image|video)\//);
|
return CoreArray.filterByRegexp(mimetypes, /^(image|video)\//);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -16,10 +16,11 @@ import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
import { CoreApp } from '@services/app';
|
import { CoreApp } from '@services/app';
|
||||||
import { CorePlatform } from '@services/platform';
|
import { CorePlatform } from '@services/platform';
|
||||||
import { CoreUtils } from '@services/utils/utils';
|
import { CoreArray } from '@singletons/array';
|
||||||
import { makeSingleton } from '@singletons';
|
import { makeSingleton } from '@singletons';
|
||||||
import { CoreFileUploaderHandler, CoreFileUploaderHandlerData, CoreFileUploaderHandlerResult } from '../fileuploader-delegate';
|
import { CoreFileUploaderHandler, CoreFileUploaderHandlerData, CoreFileUploaderHandlerResult } from '../fileuploader-delegate';
|
||||||
import { CoreFileUploaderHelper } from '../fileuploader-helper';
|
import { CoreFileUploaderHelper } from '../fileuploader-helper';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handler to record an audio to upload it.
|
* Handler to record an audio to upload it.
|
||||||
*/
|
*/
|
||||||
|
@ -42,10 +43,10 @@ export class CoreFileUploaderAudioHandlerService implements CoreFileUploaderHand
|
||||||
getSupportedMimetypes(mimetypes: string[]): string[] {
|
getSupportedMimetypes(mimetypes: string[]): string[] {
|
||||||
if (CorePlatform.isIOS()) {
|
if (CorePlatform.isIOS()) {
|
||||||
// In iOS it's recorded as WAV.
|
// In iOS it's recorded as WAV.
|
||||||
return CoreUtils.filterByRegexp(mimetypes, /^audio\/wav$/);
|
return CoreArray.filterByRegexp(mimetypes, /^audio\/wav$/);
|
||||||
} else if (CorePlatform.isAndroid()) {
|
} else if (CorePlatform.isAndroid()) {
|
||||||
// In Android we don't know the format the audio will be recorded, so accept any audio mimetype.
|
// In Android we don't know the format the audio will be recorded, so accept any audio mimetype.
|
||||||
return CoreUtils.filterByRegexp(mimetypes, /^audio\//);
|
return CoreArray.filterByRegexp(mimetypes, /^audio\//);
|
||||||
} else {
|
} else {
|
||||||
// In browser, support audio formats that are supported by MediaRecorder.
|
// In browser, support audio formats that are supported by MediaRecorder.
|
||||||
if (MediaRecorder) {
|
if (MediaRecorder) {
|
||||||
|
|
|
@ -16,7 +16,7 @@ import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
import { CoreApp } from '@services/app';
|
import { CoreApp } from '@services/app';
|
||||||
import { CorePlatform } from '@services/platform';
|
import { CorePlatform } from '@services/platform';
|
||||||
import { CoreUtils } from '@services/utils/utils';
|
import { CoreArray } from '@singletons/array';
|
||||||
import { makeSingleton } from '@singletons';
|
import { makeSingleton } from '@singletons';
|
||||||
import { CoreFileUploaderHandler, CoreFileUploaderHandlerData, CoreFileUploaderHandlerResult } from '../fileuploader-delegate';
|
import { CoreFileUploaderHandler, CoreFileUploaderHandlerData, CoreFileUploaderHandlerResult } from '../fileuploader-delegate';
|
||||||
import { CoreFileUploaderHelper } from '../fileuploader-helper';
|
import { CoreFileUploaderHelper } from '../fileuploader-helper';
|
||||||
|
@ -42,7 +42,7 @@ export class CoreFileUploaderCameraHandlerService implements CoreFileUploaderHan
|
||||||
*/
|
*/
|
||||||
getSupportedMimetypes(mimetypes: string[]): string[] {
|
getSupportedMimetypes(mimetypes: string[]): string[] {
|
||||||
// Camera only supports JPEG and PNG.
|
// Camera only supports JPEG and PNG.
|
||||||
return CoreUtils.filterByRegexp(mimetypes, /^image\/(jpeg|png)$/);
|
return CoreArray.filterByRegexp(mimetypes, /^image\/(jpeg|png)$/);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -16,10 +16,11 @@ import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
import { CoreApp } from '@services/app';
|
import { CoreApp } from '@services/app';
|
||||||
import { CorePlatform } from '@services/platform';
|
import { CorePlatform } from '@services/platform';
|
||||||
import { CoreUtils } from '@services/utils/utils';
|
import { CoreArray } from '@singletons/array';
|
||||||
import { makeSingleton } from '@singletons';
|
import { makeSingleton } from '@singletons';
|
||||||
import { CoreFileUploaderHandler, CoreFileUploaderHandlerData, CoreFileUploaderHandlerResult } from '../fileuploader-delegate';
|
import { CoreFileUploaderHandler, CoreFileUploaderHandlerData, CoreFileUploaderHandlerResult } from '../fileuploader-delegate';
|
||||||
import { CoreFileUploaderHelper } from '../fileuploader-helper';
|
import { CoreFileUploaderHelper } from '../fileuploader-helper';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handler to record a video to upload it.
|
* Handler to record a video to upload it.
|
||||||
*/
|
*/
|
||||||
|
@ -42,10 +43,10 @@ export class CoreFileUploaderVideoHandlerService implements CoreFileUploaderHand
|
||||||
getSupportedMimetypes(mimetypes: string[]): string[] {
|
getSupportedMimetypes(mimetypes: string[]): string[] {
|
||||||
if (CorePlatform.isIOS()) {
|
if (CorePlatform.isIOS()) {
|
||||||
// In iOS it's recorded as MOV.
|
// In iOS it's recorded as MOV.
|
||||||
return CoreUtils.filterByRegexp(mimetypes, /^video\/quicktime$/);
|
return CoreArray.filterByRegexp(mimetypes, /^video\/quicktime$/);
|
||||||
} else if (CorePlatform.isAndroid()) {
|
} else if (CorePlatform.isAndroid()) {
|
||||||
// In Android we don't know the format the video will be recorded, so accept any video mimetype.
|
// In Android we don't know the format the video will be recorded, so accept any video mimetype.
|
||||||
return CoreUtils.filterByRegexp(mimetypes, /^video\//);
|
return CoreArray.filterByRegexp(mimetypes, /^video\//);
|
||||||
} else {
|
} else {
|
||||||
// In browser, support video formats that are supported by MediaRecorder.
|
// In browser, support video formats that are supported by MediaRecorder.
|
||||||
if (MediaRecorder) {
|
if (MediaRecorder) {
|
||||||
|
|
|
@ -17,6 +17,7 @@ import { CoreUtils } from '@services/utils/utils';
|
||||||
import { CoreH5P } from '@features/h5p/services/h5p';
|
import { CoreH5P } from '@features/h5p/services/h5p';
|
||||||
import { Translate } from '@singletons';
|
import { Translate } from '@singletons';
|
||||||
import { CoreH5PCore, CoreH5PLibraryData, CoreH5PLibraryAddonData, CoreH5PContentDepsTreeDependency } from './core';
|
import { CoreH5PCore, CoreH5PLibraryData, CoreH5PLibraryAddonData, CoreH5PContentDepsTreeDependency } from './core';
|
||||||
|
import { CoreArray } from '@singletons/array';
|
||||||
|
|
||||||
const ALLOWED_STYLEABLE_TAGS = ['span', 'p', 'div', 'h1', 'h2', 'h3', 'td'];
|
const ALLOWED_STYLEABLE_TAGS = ['span', 'p', 'div', 'h1', 'h2', 'h3', 'td'];
|
||||||
|
|
||||||
|
@ -131,7 +132,7 @@ export class CoreH5PContentValidator {
|
||||||
tags.push('s');
|
tags.push('s');
|
||||||
}
|
}
|
||||||
|
|
||||||
tags = CoreUtils.uniqueArray(tags);
|
tags = CoreArray.unique(tags);
|
||||||
|
|
||||||
// Determine allowed style tags
|
// Determine allowed style tags
|
||||||
const stylePatterns: RegExp[] = [];
|
const stylePatterns: RegExp[] = [];
|
||||||
|
@ -372,7 +373,7 @@ export class CoreH5PContentValidator {
|
||||||
if (semantics.extraAttributes) {
|
if (semantics.extraAttributes) {
|
||||||
validKeys = validKeys.concat(semantics.extraAttributes);
|
validKeys = validKeys.concat(semantics.extraAttributes);
|
||||||
}
|
}
|
||||||
validKeys = CoreUtils.uniqueArray(validKeys);
|
validKeys = CoreArray.unique(validKeys);
|
||||||
|
|
||||||
this.filterParams(file, validKeys);
|
this.filterParams(file, validKeys);
|
||||||
|
|
||||||
|
@ -556,7 +557,7 @@ export class CoreH5PContentValidator {
|
||||||
|
|
||||||
let validKeys = ['library', 'params', 'subContentId', 'metadata'];
|
let validKeys = ['library', 'params', 'subContentId', 'metadata'];
|
||||||
if (semantics.extraAttributes) {
|
if (semantics.extraAttributes) {
|
||||||
validKeys = CoreUtils.uniqueArray(validKeys.concat(semantics.extraAttributes));
|
validKeys = CoreArray.unique(validKeys.concat(semantics.extraAttributes));
|
||||||
}
|
}
|
||||||
|
|
||||||
this.filterParams(value, validKeys);
|
this.filterParams(value, validKeys);
|
||||||
|
|
|
@ -40,6 +40,7 @@ import { CoreCancellablePromise } from '@classes/cancellable-promise';
|
||||||
import { CoreAnalytics, CoreAnalyticsEventType } from '@services/analytics';
|
import { CoreAnalytics, CoreAnalyticsEventType } from '@services/analytics';
|
||||||
import { CoreUrlUtils } from './url';
|
import { CoreUrlUtils } from './url';
|
||||||
import { QRScanner } from '@features/native/plugins';
|
import { QRScanner } from '@features/native/plugins';
|
||||||
|
import { CoreArray } from '@singletons/array';
|
||||||
|
|
||||||
export type TreeNode<T> = T & { children: TreeNode<T>[] };
|
export type TreeNode<T> = T & { children: TreeNode<T>[] };
|
||||||
|
|
||||||
|
@ -350,6 +351,7 @@ export class CoreUtilsProvider {
|
||||||
* @param from Object to copy the properties from.
|
* @param from Object to copy the properties from.
|
||||||
* @param to Object where to store the properties.
|
* @param to Object where to store the properties.
|
||||||
* @param clone Whether the properties should be cloned (so they are different instances).
|
* @param clone Whether the properties should be cloned (so they are different instances).
|
||||||
|
* @deprecated since 4.4. Not used anymore.
|
||||||
*/
|
*/
|
||||||
copyProperties(from: Record<string, unknown>, to: Record<string, unknown>, clone: boolean = true): void {
|
copyProperties(from: Record<string, unknown>, to: Record<string, unknown>, clone: boolean = true): void {
|
||||||
for (const name in from) {
|
for (const name in from) {
|
||||||
|
@ -387,6 +389,7 @@ export class CoreUtilsProvider {
|
||||||
* Empties an array without losing its reference.
|
* Empties an array without losing its reference.
|
||||||
*
|
*
|
||||||
* @param array Array to empty.
|
* @param array Array to empty.
|
||||||
|
* @deprecated since 4.4. Not used anymore.
|
||||||
*/
|
*/
|
||||||
emptyArray(array: unknown[]): void {
|
emptyArray(array: unknown[]): void {
|
||||||
array.length = 0; // Empty array without losing its reference.
|
array.length = 0; // Empty array without losing its reference.
|
||||||
|
@ -396,6 +399,7 @@ export class CoreUtilsProvider {
|
||||||
* Removes all properties from an object without losing its reference.
|
* Removes all properties from an object without losing its reference.
|
||||||
*
|
*
|
||||||
* @param object Object to remove the properties.
|
* @param object Object to remove the properties.
|
||||||
|
* @deprecated since 4.4. Not used anymore.
|
||||||
*/
|
*/
|
||||||
emptyObject(object: Record<string, unknown>): void {
|
emptyObject(object: Record<string, unknown>): void {
|
||||||
for (const key in object) {
|
for (const key in object) {
|
||||||
|
@ -482,17 +486,10 @@ export class CoreUtilsProvider {
|
||||||
* @param array Array to filter.
|
* @param array Array to filter.
|
||||||
* @param regex RegExp to apply to each string.
|
* @param regex RegExp to apply to each string.
|
||||||
* @returns Filtered array.
|
* @returns Filtered array.
|
||||||
|
* @deprecated since 4.4. Use CoreArray.filterByRegexp instead.
|
||||||
*/
|
*/
|
||||||
filterByRegexp(array: string[], regex: RegExp): string[] {
|
filterByRegexp(array: string[], regex: RegExp): string[] {
|
||||||
if (!array || !array.length) {
|
return CoreArray.filterByRegexp(array, regex);
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
return array.filter((entry) => {
|
|
||||||
const matches = entry.match(regex);
|
|
||||||
|
|
||||||
return matches && matches.length;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -956,7 +953,7 @@ export class CoreUtilsProvider {
|
||||||
* @returns Merged array.
|
* @returns Merged array.
|
||||||
*/
|
*/
|
||||||
mergeArraysWithoutDuplicates<T>(array1: T[], array2: T[], key?: string): T[] {
|
mergeArraysWithoutDuplicates<T>(array1: T[], array2: T[], key?: string): T[] {
|
||||||
return this.uniqueArray(array1.concat(array2), key) as T[];
|
return CoreArray.unique(array1.concat(array2), key) as T[];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1390,6 +1387,7 @@ export class CoreUtilsProvider {
|
||||||
* @param data Object.
|
* @param data Object.
|
||||||
* @param prefix Prefix to add.
|
* @param prefix Prefix to add.
|
||||||
* @returns Prefixed object.
|
* @returns Prefixed object.
|
||||||
|
* @deprecated since 4.4. Not used anymore.
|
||||||
*/
|
*/
|
||||||
prefixKeys(data: Record<string, unknown>, prefix: string): Record<string, unknown> {
|
prefixKeys(data: Record<string, unknown>, prefix: string): Record<string, unknown> {
|
||||||
const newObj = {};
|
const newObj = {};
|
||||||
|
@ -1611,21 +1609,10 @@ export class CoreUtilsProvider {
|
||||||
* @param array The array to treat.
|
* @param array The array to treat.
|
||||||
* @param [key] Key of the property that must be unique. If not specified, the whole entry.
|
* @param [key] Key of the property that must be unique. If not specified, the whole entry.
|
||||||
* @returns Array without duplicate values.
|
* @returns Array without duplicate values.
|
||||||
|
* @deprecated since 4.4. Use CoreArray.unique instead.
|
||||||
*/
|
*/
|
||||||
uniqueArray<T>(array: T[], key?: string): T[] {
|
uniqueArray<T>(array: T[], key?: string): T[] {
|
||||||
const unique = {}; // Use an object to make it faster to check if it's duplicate.
|
return CoreArray.unique(array, key);
|
||||||
|
|
||||||
return array.filter(entry => {
|
|
||||||
const value = key ? entry[key] : entry;
|
|
||||||
|
|
||||||
if (value in unique) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
unique[value] = true;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -66,4 +66,46 @@ export class CoreArray {
|
||||||
return newArray;
|
return newArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return an array without duplicate values.
|
||||||
|
*
|
||||||
|
* @param array The array to treat.
|
||||||
|
* @param [key] Key of the property that must be unique. If not specified, the whole entry.
|
||||||
|
* @returns Array without duplicate values.
|
||||||
|
*/
|
||||||
|
static unique<T>(array: T[], key?: string): T[] {
|
||||||
|
const unique = {}; // Use an object to make it faster to check if it's duplicate.
|
||||||
|
|
||||||
|
return array.filter(entry => {
|
||||||
|
const value = key ? entry[key] : entry;
|
||||||
|
|
||||||
|
if (value in unique) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
unique[value] = true;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given an array of strings, return only the ones that match a regular expression.
|
||||||
|
*
|
||||||
|
* @param array Array to filter.
|
||||||
|
* @param regex RegExp to apply to each string.
|
||||||
|
* @returns Filtered array.
|
||||||
|
*/
|
||||||
|
static filterByRegexp(array: string[], regex: RegExp): string[] {
|
||||||
|
if (!array || !array.length) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return array.filter((entry) => {
|
||||||
|
const matches = entry.match(regex);
|
||||||
|
|
||||||
|
return matches && matches.length;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,4 +23,18 @@ describe('CoreArray singleton', () => {
|
||||||
expect(CoreArray.withoutItem(originalArray, 'not found')).toEqual(['foo', 'bar', 'baz']);
|
expect(CoreArray.withoutItem(originalArray, 'not found')).toEqual(['foo', 'bar', 'baz']);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('gets unique array', () => {
|
||||||
|
const originalArray = ['foo', 'bar', 'foo', 'baz'];
|
||||||
|
|
||||||
|
expect(CoreArray.unique(originalArray)).toEqual(['foo', 'bar', 'baz']);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('filters array by regexp', () => {
|
||||||
|
const originalArray = ['foo', 'bar', 'baz', 'qux'];
|
||||||
|
|
||||||
|
expect(CoreArray.filterByRegexp(originalArray, /ba/)).toEqual(['bar', 'baz']);
|
||||||
|
expect(CoreArray.filterByRegexp(originalArray, /foo/)).toEqual(['foo']);
|
||||||
|
expect(CoreArray.filterByRegexp([], /foo/)).toEqual([]);
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue