Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/en/v1/api/array/find.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ prev:
text: "isLastIndex"
link: "/en/v1/api/array/isLastIndex"
next:
text: "findLast"
link: "/en/v1/api/array/findLast"
text: "findDuplicates"
link: "/en/v1/api/array/findDuplicates"
---

# find
Expand Down
48 changes: 48 additions & 0 deletions docs/en/v1/api/array/findDuplicates.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
---
outline: [2, 3]
description: "The findDuplicates() function returns duplicated values from an array and keeps a single occurrence for each duplicated value."
prev:
text: "find"
link: "/en/v1/api/array/find"
next:
text: "findLast"
link: "/en/v1/api/array/findLast"
---

# findDuplicates

The **`findDuplicates()`** function returns duplicated values from an array and keeps a single occurrence for each duplicated value.

## Interactive example

<MonacoTSEditor
src="/examples/v1/api/array/findDuplicates/tryout.doc.ts"
majorVersion="v1"
height="565px"
/>

## Syntax

### Classic signature

```typescript
function findDuplicates<
GenericInput extends readonly EligibleDuplicateElement[],
>(
array: GenericInput,
): undefined | AnyTuple<GenericInput[number]>
```

## Parameters

- `array`: Input array to scan for duplicates.

## Return value

Returns `undefined` when no duplicate is found, otherwise returns a tuple containing duplicated values (one occurrence per value).

## See also

- [`find`](/en/v1/api/array/find) - Finds a value matching a predicate
- [`group`](/en/v1/api/array/group) - Groups values by key
- [`includes`](/en/v1/api/array/includes) - Checks value presence in an array
4 changes: 2 additions & 2 deletions docs/en/v1/api/array/findLast.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
outline: [2, 3]
description: "The findLast() method returns the last element of an array that satisfies a given condition."
prev:
text: "find"
link: "/en/v1/api/array/find"
text: "findDuplicates"
link: "/en/v1/api/array/findDuplicates"
next:
text: "findIndex"
link: "/en/v1/api/array/findIndex"
Expand Down
3 changes: 3 additions & 0 deletions docs/en/v1/api/array/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ Indicates whether an index corresponds to the last element of the array.
### [find](/en/v1/api/array/find)
Finds the first element that satisfies a condition.

### [findDuplicates](/en/v1/api/array/findDuplicates)
Finds duplicated values and keeps one occurrence per duplicate.

### [findLast](/en/v1/api/array/findLast)
Finds the last element that satisfies a condition.

Expand Down
25 changes: 25 additions & 0 deletions docs/examples/v1/api/array/findDuplicates/tryout.doc.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { A, DDate, pipe, type ExpectType } from "@duplojs/utils";

const primitiveResult = A.findDuplicates(["apple", "banana", "apple", "banana", "pear"]);
// ["apple", "banana"]

const dateValue = DDate.create("2024-01-01");
const timeValue = DDate.createTime(90, "minute");
const dateAndTimeResult = A.findDuplicates([
dateValue,
DDate.create("2024-01-01"),
timeValue,
DDate.createTime(90, "minute"),
]);
// [dateValue, timeValue]

const pipedResult = pipe(
[true, false, true, false],
A.findDuplicates,
);

type check = ExpectType<
typeof pipedResult,
undefined | readonly [boolean, ...boolean[]],
"strict"
>;
4 changes: 2 additions & 2 deletions docs/fr/v1/api/array/find.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ prev:
text: "isLastIndex"
link: "/fr/v1/api/array/isLastIndex"
next:
text: "findLast"
link: "/fr/v1/api/array/findLast"
text: "findDuplicates"
link: "/fr/v1/api/array/findDuplicates"
---

# find
Expand Down
48 changes: 48 additions & 0 deletions docs/fr/v1/api/array/findDuplicates.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
---
outline: [2, 3]
description: "La fonction findDuplicates() retourne les valeurs dupliquées d'un tableau et conserve une seule occurrence pour chaque valeur dupliquée."
prev:
text: "find"
link: "/fr/v1/api/array/find"
next:
text: "findLast"
link: "/fr/v1/api/array/findLast"
---

# findDuplicates

La fonction **`findDuplicates()`** retourne les valeurs dupliquées d'un tableau et conserve une seule occurrence pour chaque valeur dupliquée.

## Exemple interactif

<MonacoTSEditor
src="/examples/v1/api/array/findDuplicates/tryout.doc.ts"
majorVersion="v1"
height="565px"
/>

## Syntaxe

### Signature classique

```typescript
function findDuplicates<
GenericInput extends readonly EligibleDuplicateElement[],
>(
array: GenericInput,
): undefined | AnyTuple<GenericInput[number]>
```

## Paramètres

- `array` : Tableau d'entrée à parcourir pour détecter les doublons.

## Valeur de retour

Retourne `undefined` lorsqu'aucun doublon n'est trouvé, sinon retourne un tuple contenant les valeurs dupliquées (une occurrence par valeur).

## Voir aussi

- [`find`](/fr/v1/api/array/find) - Trouve une valeur correspondant à un prédicat
- [`group`](/fr/v1/api/array/group) - Regroupe les valeurs par clé
- [`includes`](/fr/v1/api/array/includes) - Vérifie la présence d'une valeur dans un tableau
4 changes: 2 additions & 2 deletions docs/fr/v1/api/array/findLast.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
outline: [2, 3]
description: "La méthode findLast() retourne le dernier élément d'un tableau qui satisfait une condition donnée."
prev:
text: "find"
link: "/fr/v1/api/array/find"
text: "findDuplicates"
link: "/fr/v1/api/array/findDuplicates"
next:
text: "findIndex"
link: "/fr/v1/api/array/findIndex"
Expand Down
3 changes: 3 additions & 0 deletions docs/fr/v1/api/array/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ Indique si un index correspond au dernier élément du tableau.
### [find](/fr/v1/api/array/find)
Trouve le premier élément qui satisfait une condition.

### [findDuplicates](/fr/v1/api/array/findDuplicates)
Trouve les valeurs dupliquées et conserve une occurrence par doublon.

### [findLast](/fr/v1/api/array/findLast)
Trouve le dernier élément qui satisfait une condition.

Expand Down
38 changes: 38 additions & 0 deletions docs/public/libs/v1/array/findDuplicates.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
'use strict';

var is = require('../date/is.cjs');
var isTime = require('../date/isTime.cjs');

function findDuplicates(array) {
const store = new Map();
let storeTimeObject = undefined;
let result = undefined;
for (let index$1 = 0; index$1 < array.length; index$1++) {
const element = array[index$1];
if (is.is(element) || isTime.isTime(element)) {
storeTimeObject ??= new Map();
const serializedValue = element.toJSON();
const storedElement = storeTimeObject.get(serializedValue) ?? element;
const storedCount = store.get(storedElement);
if (storedCount === 1) {
result ??= [];
result.push(storedElement);
}
store.set(storedElement, (storedCount ?? 0) + 1);
if (storedElement === element) {
storeTimeObject.set(serializedValue, element);
}
}
else {
const storedCount = store.get(element);
if (storedCount === 1) {
result ??= [];
result.push(element);
}
store.set(element, (storedCount ?? 0) + 1);
}
}
return result;
}

exports.findDuplicates = findDuplicates;
4 changes: 4 additions & 0 deletions docs/public/libs/v1/array/findDuplicates.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { type AnyTuple } from "../common";
import * as DDate from "../date";
export type EligibleDuplicateElement = (string | boolean | null | number | bigint | undefined | DDate.TheDate | DDate.TheTime);
export declare function findDuplicates<GenericInput extends readonly EligibleDuplicateElement[]>(array: GenericInput): undefined | AnyTuple<GenericInput[number]>;
36 changes: 36 additions & 0 deletions docs/public/libs/v1/array/findDuplicates.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { is } from '../date/is.mjs';
import { isTime } from '../date/isTime.mjs';

function findDuplicates(array) {
const store = new Map();
let storeTimeObject = undefined;
let result = undefined;
for (let index$1 = 0; index$1 < array.length; index$1++) {
const element = array[index$1];
if (is(element) || isTime(element)) {
storeTimeObject ??= new Map();
const serializedValue = element.toJSON();
const storedElement = storeTimeObject.get(serializedValue) ?? element;
const storedCount = store.get(storedElement);
if (storedCount === 1) {
result ??= [];
result.push(storedElement);
}
store.set(storedElement, (storedCount ?? 0) + 1);
if (storedElement === element) {
storeTimeObject.set(serializedValue, element);
}
}
else {
const storedCount = store.get(element);
if (storedCount === 1) {
result ??= [];
result.push(element);
}
store.set(element, (storedCount ?? 0) + 1);
}
}
return result;
}

export { findDuplicates };
2 changes: 2 additions & 0 deletions docs/public/libs/v1/array/index.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ var isLastIndex = require('./isLastIndex.cjs');
var select = require('./select.cjs');
var lengthEqual = require('./lengthEqual.cjs');
var mapTuple = require('./mapTuple.cjs');
var findDuplicates = require('./findDuplicates.cjs');
var _delete = require('./splice/delete.cjs');
var insert = require('./splice/insert.cjs');
var replace = require('./splice/replace.cjs');
Expand Down Expand Up @@ -110,6 +111,7 @@ exports.select = select.select;
exports.selectTools = select.selectTools;
exports.lengthEqual = lengthEqual.lengthEqual;
exports.mapTuple = mapTuple.mapTuple;
exports.findDuplicates = findDuplicates.findDuplicates;
exports.spliceDelete = _delete.spliceDelete;
exports.spliceInsert = insert.spliceInsert;
exports.spliceReplace = replace.spliceReplace;
Expand Down
1 change: 1 addition & 0 deletions docs/public/libs/v1/array/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,4 @@ export * from "./isLastIndex";
export * from "./select";
export * from "./lengthEqual";
export * from "./mapTuple";
export * from "./findDuplicates";
1 change: 1 addition & 0 deletions docs/public/libs/v1/array/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export { isLastIndex } from './isLastIndex.mjs';
export { select, selectTools } from './select.mjs';
export { lengthEqual } from './lengthEqual.mjs';
export { mapTuple } from './mapTuple.mjs';
export { findDuplicates } from './findDuplicates.mjs';
export { spliceDelete } from './splice/delete.mjs';
export { spliceInsert } from './splice/insert.mjs';
export { spliceReplace } from './splice/replace.mjs';
Expand Down
2 changes: 1 addition & 1 deletion docs/public/libs/v1/clean/constraint/base.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ export interface ConstraintHandler<GenericName extends string = string, GenericP
}
declare const CreateConstrainedTypeError_base: new (params: {
"@DuplojsUtilsError/create-constrained-type-error"?: unknown;
}, parentParams: readonly [message?: string | undefined, options?: ErrorOptions | undefined]) => Error & Kind<import("../..").KindDefinition<"create-constrained-type-error", unknown>, unknown> & Kind<import("../..").KindDefinition<"@DuplojsUtilsError/create-constrained-type-error", unknown>, unknown>;
}, parentParams: readonly [message?: string | undefined, options?: ErrorOptions | undefined]) => Error & Kind<import("../..").KindDefinition<"@DuplojsUtilsError/create-constrained-type-error", unknown>, unknown> & Kind<import("../..").KindDefinition<"create-constrained-type-error", unknown>, unknown>;
export declare class CreateConstrainedTypeError extends CreateConstrainedTypeError_base {
constrainedTypeName: string;
data: unknown;
Expand Down
2 changes: 1 addition & 1 deletion docs/public/libs/v1/clean/constraint/set.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ export interface ConstraintsSetHandler<GenericPrimitiveValue extends EligiblePri
}
declare const CreateConstraintsSetError_base: new (params: {
"@DuplojsUtilsError/create-constraint-set-error"?: unknown;
}, parentParams: readonly [message?: string | undefined, options?: ErrorOptions | undefined]) => Error & Kind<import("../..").KindDefinition<"create-constraint-set-error", unknown>, unknown> & Kind<import("../..").KindDefinition<"@DuplojsUtilsError/create-constraint-set-error", unknown>, unknown>;
}, parentParams: readonly [message?: string | undefined, options?: ErrorOptions | undefined]) => Error & Kind<import("../..").KindDefinition<"@DuplojsUtilsError/create-constraint-set-error", unknown>, unknown> & Kind<import("../..").KindDefinition<"create-constraint-set-error", unknown>, unknown>;
export declare class CreateConstraintsSetError extends CreateConstraintsSetError_base {
data: unknown;
dataParserError: DDataParser.DataParserError;
Expand Down
2 changes: 1 addition & 1 deletion docs/public/libs/v1/clean/entity/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ export interface EntityHandler<GenericName extends string = string, GenericPrope
}
declare const CreateEntityError_base: new (params: {
"@DuplojsUtilsError/create-entity-error"?: unknown;
}, parentParams: readonly [message?: string | undefined, options?: ErrorOptions | undefined]) => Error & Kind<import("../../common").KindDefinition<"create-entity-error", unknown>, unknown> & Kind<import("../../common").KindDefinition<"@DuplojsUtilsError/create-entity-error", unknown>, unknown>;
}, parentParams: readonly [message?: string | undefined, options?: ErrorOptions | undefined]) => Error & Kind<import("../../common").KindDefinition<"@DuplojsUtilsError/create-entity-error", unknown>, unknown> & Kind<import("../../common").KindDefinition<"create-entity-error", unknown>, unknown>;
export declare class CreateEntityError extends CreateEntityError_base {
rawProperties: PropertiesToMapOfEntity;
dataParserError: DDataParser.DataParserError;
Expand Down
10 changes: 5 additions & 5 deletions docs/public/libs/v1/clean/flag.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export interface FlagHandler<GenericEntity extends Entity = Entity, GenericName
* export function isMajor(entity: Entity) {
* if (C.greaterThan(entity.age, 18)) {
* return E.success(
* MajorFlag.append(entity, entity.age),
* MajorFlag.append(entity, { age: entity.age }),
* );
* ```
*
Expand All @@ -26,7 +26,7 @@ export interface FlagHandler<GenericEntity extends Entity = Entity, GenericName
* Retrieves the value carried by the flag.
*
* ```ts
* const flagged = User.MajorFlag.append(user, user.age);
* const flagged = User.MajorFlag.append(user, { age: user.age });
* const value = User.MajorFlag.getValue(flagged);
* ```
*
Expand Down Expand Up @@ -61,14 +61,14 @@ export interface Flag<GenericName extends string = string, GenericValue extends
* export const MajorFlag = C.createFlag<
* Entity, // mandatory
* "majorUser", // mandatory
* Age // optional
* { age: Age } // optional
* >("majorUser");
* export type MajorFlag = C.GetFlag<typeof MajorFlag>;
*
* export function isMajor(entity: Entity) {
* if (C.greaterThan(entity.age, 18)) {
* return E.success(
* MajorFlag.append(entity, entity.age),
* MajorFlag.append(entity, { age: entity.age }),
* );
* }
* return E.left("not-major");
Expand All @@ -94,7 +94,7 @@ export interface Flag<GenericName extends string = string, GenericValue extends
* );
* // E.Left<"not-major", undefined> | E.Right<"not-thirsty-anymore", undefined>
*
* const flagged = User.MajorFlag.append(user, user.age);
* const flagged = User.MajorFlag.append(user, { age: user.age });
* const value = User.MajorFlag.getValue(flagged);
*
* ```
Expand Down
2 changes: 1 addition & 1 deletion docs/public/libs/v1/clean/newType.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ export interface NewTypeHandler<GenericName extends string = string, GenericValu
}
declare const CreateNewTypeError_base: new (params: {
"@DuplojsUtilsError/create-new-type-error"?: unknown;
}, parentParams: readonly [message?: string | undefined, options?: ErrorOptions | undefined]) => Error & Kind<import("..").KindDefinition<"create-new-type-error", unknown>, unknown> & Kind<import("..").KindDefinition<"@DuplojsUtilsError/create-new-type-error", unknown>, unknown>;
}, parentParams: readonly [message?: string | undefined, options?: ErrorOptions | undefined]) => Error & Kind<import("..").KindDefinition<"@DuplojsUtilsError/create-new-type-error", unknown>, unknown> & Kind<import("..").KindDefinition<"create-new-type-error", unknown>, unknown>;
export declare class CreateNewTypeError extends CreateNewTypeError_base {
newTypeName: string;
data: unknown;
Expand Down
2 changes: 1 addition & 1 deletion docs/public/libs/v1/clean/primitive/base.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export interface PrimitiveHandler<GenericValue extends EligiblePrimitive = Eligi
}
declare const CreatePrimitiveError_base: new (params: {
"@DuplojsUtilsError/create-primitive-error"?: unknown;
}, parentParams: readonly [message?: string | undefined, options?: ErrorOptions | undefined]) => Error & Kind<import("../../common").KindDefinition<"create-primitive-error", unknown>, unknown> & Kind<import("../../common").KindDefinition<"@DuplojsUtilsError/create-primitive-error", unknown>, unknown>;
}, parentParams: readonly [message?: string | undefined, options?: ErrorOptions | undefined]) => Error & Kind<import("../../common").KindDefinition<"@DuplojsUtilsError/create-primitive-error", unknown>, unknown> & Kind<import("../../common").KindDefinition<"create-primitive-error", unknown>, unknown>;
export declare class CreatePrimitiveError extends CreatePrimitiveError_base {
data: unknown;
dataParserError: DDataParser.DataParserError;
Expand Down
Loading
Loading