I have a problem that should be trivial but to which I can't find any elegant answer.
I have an instance of a IList<string>
and I want to get a comma-separated string of all its distinct (case-insensitive) values.
I thought I'd just use the string.Join
helper for that since it has a nice overload that accepts an IEnumerator<string>
as parameter. Unfortunately, I see to have hit a snag: spring4d redefines IEnumerator<T>
and, of course, use its own type everywhere.
The result is that the following code does not compile:
var
distinct: system.IEnumerator<string>;
begin
result := inherited GetToken;
if assigned(result) then
begin
if not Modules.Contains(STR_DID_SESSION_MODULE) then
Modules.Add(STR_DID_SESSION_MODULE);
distinct := TDistinctIterator<string>.Create(Modules, TIStringComparer.Ordinal);
result.CustomClaims.Items[STR_CLAIM_CUSTOM_MODULES] := string.Join(',', distinct);
end;
end;
The assignment to distinct
fails with E2010 Incompatible types: 'System.IEnumerator<System.string>' and 'Spring.Collections.Extensions.TDistinctIterator<System.string>'
Alternatively, if I remove the namespace from distinct, it's the call to string.Join
that fails.
Any idea how I should be doing that ? Short of manually walking through the iteration and performing the join manually?
Write it yourself (FWIW I would prefer opposite parameter order but I kept it like that since the signature of TStringHelper.Join
):
function StringJoin(const separator: string; const values: Spring.Collections.IEnumerable<string>): string; overload;
var
e: Spring.Collections.IEnumerator<string>;
begin
e := values.GetEnumerator;
if not e.MoveNext then
Exit('');
Result := e.Current;
while e.MoveNext do
Result := Result + separator + e.Current;
end;
Also you can write the code way shorter (no need to manually create the iterator from Spring.Collections.Extensions
):
StringJoin(',', TEnumerable.Distinct<string>(Modules, TStringComparer.OrdinalIgnoreCase))
Now if we had interface helpers we could easily write a helper for IEnumerable<string>
and add ToDelimitedString
or something like that.