Generic set comparer

Recommended Posts

Is there a mature library for generic (multi)set operations?

(Edit: Reading my topic, i meant mathematical sets, maybe I could name it List instead of set, the result what counts)

I'd imagine that working like this:

```unit xyz.sets;

interface

uses
System.Generics.Defaults;

type
TSets<T> = class
public type
TSet = class
private
FValues: TArray<T>;
public
end;
private
var
FSets: TArray<TSet>;
FComparer: IEqualityComparer<T>;
public
constructor Create;
function GetIntersection(ASets: array of TSet): TArray<T>;
property Comparer: IEqualityComparer<T> read FComparer write FComparer;
end;

implementation

uses
System.SysUtils;

{ TSets<T> }

var
l: integer;
begin
Result := TSet.Create;
l := Length(FSets);
SetLength(FSets, l + 1);
FSets[l] := Result;
end;

{ TSets<T>.TSet }

var
l: integer;
begin
l := Length(FValues);
SetLength(FValues, l + 1);
FValues[l] := AValue;
end;

constructor TSets<T>.Create;
begin
FComparer := TEqualityComparer<T>.Default;
end;

// O(n^x)
function TSets<T>.GetIntersection(ASets: array of TSet): TArray<T>;
var
i, j, k, l: integer;
begin
if FComparer = nil then
raise Exception.Create('No comparer defined.');
if Length(ASets) > 1 then
begin
for i := 0 to High(ASets[0].FValues) do
for j := 1 to High(ASets) do
for k := 0 to High(ASets[j].FValues) do
if FComparer.Equals(ASets[0].FValues[i], ASets[j].FValues[k]) then
begin
l := Length(Result);
SetLength(Result, l + 1);
Result[l] := ASets[0].FValues[i];
end;
end
else
Result := ASets[0].FValues;
end;

end.

------ ✂ ------ ✂ ------ ✂ ------ ✂ ------ ✂ ------ ✂ ------ ✂ ------ ✂ ------

program Project1;

{\$APPTYPE CONSOLE}
{\$R *.res}

uses
System.SysUtils,
xyz.sets in 'xyz.sets.pas';

var
rp: procedure;

i: integer;
sets: TSets<string>;
set1, set2: TSets<string>.TSet;
res: TArray<string>;

procedure x;
begin
ExitProcessProc := rp;
end;

begin
ReportMemoryLeaksOnShutdown := True;
rp := ExitProcessProc;
ExitProcessProc := x;

sets := TSets<string>.Create;
try

res := sets.GetIntersection([set1, set2]);
for i := 0 to High(res) do
WriteLn(res[i]);

finally
set1.Free;
set2.Free;
sets.Free;
end;

end.```

Edited by Attila Kovacs

Not aware of any library, but I have written small routines like

function AnyOf(ATarget, AActual: TOptionSet): Boolean;  and

function Contains(ATarget, AActual: TOptionSet): Boolean;

Makes the code more readable, I think, which is all I really needed. My notion was that although the set operations are pretty terse, not a lot of devs spend much time reading them, so comprehension may be a struggle. AnyOf() handles any members of the target being present in the actual:

Result := ATarget * AActual <> [];

while Contains() tests:

Result := ATarget * AActual = ATarget;

Unless your need is for a lot of densely coded operations, this kind of thing may be sufficient. If you do need dense code, then you may better simply use the existing operators.

Ahm, i was afraid that using the word "set" would be misleading, and I was right, sorry, but lists are a bit different from multisets again, so I don't know,

I need to compare two or more "set of anything" and I'm tired writing it always manually.

24 minutes ago, Attila Kovacs said:

Ahm, i was afraid that using the word "set" would be misleading, and I was right, sorry, but lists are a bit different from multisets again, so I don't know,

I need to compare two or more "set of anything" and I'm tired writing it always manually.

Ah, I did indeed misunderstand. So really, you want set operations on collections of whatever type.

@Leif Uneus Wow, thanks a lot, and also to LU RD if he ever reads this.

Spring4D has ISet<T> and 2.0 will introduce IMultiSet<T>

• 4

2 hours ago, Attila Kovacs said:

@Leif Uneus Wow, thanks a lot, and also to LU RD if he ever reads this.﻿

Well. there is no secret that LU RD is short for Leif Uneus R&D Manager of Opsis AB, a company that provides analysers and software for industrial and environmental analysis of gases and particulates.

A company started 36 years ago by me and my business partner.

Core software in the analysers is built with Turbo Pascal 7. Delphi is a tool for our software for data management, analysis and reporting.

Edited by Leif Uneus
• 1

LOL <o>, well, now it's revealed! 😉

• 1

solved, user error.

Edited by Attila Kovacs

Can we please sit for a while and appreciate how cute the separating line with scissors is

• 2