Recent

Author Topic: [SOLVED] How to pass dynamic array to String.Join()?  (Read 1978 times)

artem101

  • Jr. Member
  • **
  • Posts: 84
[SOLVED] How to pass dynamic array to String.Join()?
« on: June 01, 2022, 11:27:17 am »
Code: Pascal  [Select][+][-]
  1. program Project1;
  2.  
  3. uses SysUtils;
  4.  
  5. var
  6.   s: string;
  7.   a: array of cardinal;
  8.  
  9. begin
  10.   setlength(a, 3);
  11.   a[0]:=5;
  12.   a[1]:=8;
  13.   a[2]:=99;
  14.  
  15.   s := string.join(',', a);
  16.  
  17.   writeln(s);
  18.  
  19.   readln;
  20. end.

This code gives me an error:
Quote
project1.lpr(15,24) Error: Incompatible type for arg no. 2: Got "{Dynamic} Array Of LongWord", expected "{Open} Array Of AnsiString"

What is wrong?

Lazarus: 2.0.12; FPC: 3.2.0; Windows 7 64bit
« Last Edit: June 02, 2022, 01:28:29 pm by artem101 »

Bart

  • Hero Member
  • *****
  • Posts: 5290
    • Bart en Mariska's Webstek
Re: How to pass dynamic array to String.Join()?
« Reply #1 on: June 01, 2022, 11:33:37 am »
Join works on array's of string, not on array's of any other type.
The errormessage tells you.

Bart

Thaddy

  • Hero Member
  • *****
  • Posts: 14373
  • Sensorship about opinions does not belong here.
Re: How to pass dynamic array to String.Join()?
« Reply #2 on: June 01, 2022, 11:51:39 am »
No, Join works on equal types, here OP uses unequal types: string vs cardinal.
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

Zvoni

  • Hero Member
  • *****
  • Posts: 2327
Re: How to pass dynamic array to String.Join()?
« Reply #3 on: June 01, 2022, 11:55:31 am »
No, Join works on equal types, here OP uses unequal types: string vs cardinal.
Huh? What are you smoking (and why don't you share?)
https://www.freepascal.org/docs-html/rtl/sysutils/tstringhelper.join.html
Quote
Values can be an array of strings, but can also be an array of arbitrary values: the values will first be transformed to a string representation first.
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

Thaddy

  • Hero Member
  • *****
  • Posts: 14373
  • Sensorship about opinions does not belong here.
Re: How to pass dynamic array to String.Join()?
« Reply #4 on: June 01, 2022, 11:59:27 am »
It is called InsertRange, Sorry, but that is the same as join.....
generics.collections.
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

artem101

  • Jr. Member
  • **
  • Posts: 84
Re: How to pass dynamic array to String.Join()?
« Reply #5 on: June 01, 2022, 12:09:04 pm »
https://www.freepascal.org/docs-html/rtl/sysutils/tstringhelper.join.html
Quote
Values can be an array of strings, but can also be an array of arbitrary values: the values will first be transformed to a string representation first.

You are right - types can be any. This example works correctly:
Code: Pascal  [Select][+][-]
  1. var
  2.   x: integer;
  3.   y: cardinal;
  4.   s: string;
  5.  
  6. begin
  7.   x := 45;
  8.   y := 909;
  9.   s := string.join(',', ['hello', 5, 3.13, false, x, y]);
  10.   writeln(s);
  11.   readln;
  12. end.

Problem only with dynamic arrays.

Zvoni

  • Hero Member
  • *****
  • Posts: 2327
Re: How to pass dynamic array to String.Join()?
« Reply #6 on: June 01, 2022, 12:10:42 pm »
hmmm.... this works:
Code: Pascal  [Select][+][-]
  1. s := string.Join(',', [5,8,99]);    
  2.  
So Bart is basically right, that if you pass an array, it must be array of string
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

Zvoni

  • Hero Member
  • *****
  • Posts: 2327
Re: How to pass dynamic array to String.Join()?
« Reply #7 on: June 01, 2022, 12:11:50 pm »
Problem only with dynamic arrays.
Wrong.
This works:
Code: Pascal  [Select][+][-]
  1. program Project1;
  2.  
  3. uses SysUtils;
  4.  
  5. var
  6.   s: string;
  7.   a: array of String;  //-->!!!!!!
  8.  
  9. begin
  10.   setlength(a, 3);
  11.   a[0]:='5';  //Note the Quotes
  12.   a[1]:='8'; //Note the Quotes
  13.   a[2]:='99'; //Note the Quotes
  14.  
  15.   s := string.Join(',', a);
  16.  
  17.   writeln(s);
  18.  
  19.   readln;
  20. end.
  21.  

What are you trying to achieve?
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

artem101

  • Jr. Member
  • **
  • Posts: 84
Re: How to pass dynamic array to String.Join()?
« Reply #8 on: June 01, 2022, 12:20:37 pm »
Zvoni, you example works. But why this not works with dynamic array of numeric types?

Zvoni

  • Hero Member
  • *****
  • Posts: 2327
Re: How to pass dynamic array to String.Join()?
« Reply #9 on: June 01, 2022, 12:26:11 pm »
Zvoni, you example works. But why this not works with dynamic array of numeric types?
Now it works:
Change type to suit (i used integer)
Code: Pascal  [Select][+][-]
  1. program Project1;
  2. {$modeswitch TypeHelpers}
  3.  
  4. uses SysUtils;
  5. Type
  6.   TJoinInteger=Type helper(TStringHelper) for AnsiString
  7.     class function Join(const Separator: string; const Values: array of Integer): string; overload; static;
  8.   end;
  9.  
  10. class function TJoinInteger.Join(const Separator: string;
  11.   const Values: array of Integer): string;
  12. Var
  13.   SValues:Array Of String;
  14.   i:SizeInt;
  15. begin
  16.   SetLength(SValues,System.Length(Values));
  17.   For i:=Low(SValues) To High(SValues) Do SValues[i]:=Values[i].ToString;
  18.   Result:=Join(Separator,SValues);
  19. end;
  20.  
  21.  
  22. var
  23.   s: string;
  24.   a: array of Integer;
  25.  
  26. begin
  27.   setlength(a, 3);
  28.   a[0]:=5;
  29.   a[1]:=8;
  30.   a[2]:=99;
  31.  
  32.   s := string.Join(',', a);
  33.  
  34.   writeln(s);
  35.  
  36.   readln;
  37. end.
« Last Edit: June 01, 2022, 12:30:07 pm by Zvoni »
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

artem101

  • Jr. Member
  • **
  • Posts: 84
Re: How to pass dynamic array to String.Join()?
« Reply #10 on: June 01, 2022, 12:34:04 pm »
Now it works:
Change type to suit (i used integer)

Really works. Thanks!

Interesting solution - I have never deal with type helpers.
« Last Edit: June 01, 2022, 12:45:16 pm by artem101 »

PascalDragon

  • Hero Member
  • *****
  • Posts: 5481
  • Compiler Developer
Re: How to pass dynamic array to String.Join()?
« Reply #11 on: June 01, 2022, 01:28:50 pm »
Zvoni, you example works. But why this not works with dynamic array of numeric types?

Because the overload for any values is for an array of const. Dynamic arrays are not compatible to array of const while a dynamic String array can be passed to array of String parameter (which is not a dynamic array, but an open array).

Interesting solution - I have never deal with type helpers.

Well, essentially you do, cause the String.Join is precisely that... ;)

Zvoni

  • Hero Member
  • *****
  • Posts: 2327
Re: How to pass dynamic array to String.Join()?
« Reply #12 on: June 01, 2022, 01:45:42 pm »
Because the overload for any values is for an array of const. Dynamic arrays are not compatible to array of const while a dynamic String array can be passed to array of String parameter (which is not a dynamic array, but an open array).
Out of Curiosity:
Is this because in a nutshell an "array of const" is an array of literals? like [1,5,18],
as in: we're throwing literal values on the stack, and not a memory-address to a variable
(and yes, i've looked at the Source-code for the overloaded "Join", where you check the Type to use the correct "transformation" to String)
« Last Edit: June 01, 2022, 01:47:40 pm by Zvoni »
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1314
    • Lebeau Software
Re: How to pass dynamic array to String.Join()?
« Reply #13 on: June 01, 2022, 10:43:30 pm »
Out of Curiosity:
Is this because in a nutshell an "array of const" is an array of literals? like [1,5,18],

No, it is because "array of const" is really "array of TVarRec" (which can be used with variables as well as literals).  You simply can't pass in a dynamic "array of string" to an "array of TVarRec", they are two different types of arrays.
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

Zvoni

  • Hero Member
  • *****
  • Posts: 2327
Re: How to pass dynamic array to String.Join()?
« Reply #14 on: June 02, 2022, 08:30:56 am »
Out of Curiosity:
Is this because in a nutshell an "array of const" is an array of literals? like [1,5,18],

No, it is because "array of const" is really "array of TVarRec" (which can be used with variables as well as literals).  You simply can't pass in a dynamic "array of string" to an "array of TVarRec", they are two different types of arrays.
Ahhh, OK.
Thx Remy
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

 

TinyPortal © 2005-2018