Creative Uses of Strings

Read(2349) Label: string, eval,

In esProc, strings are not merely a data type; they can be used as macros or string constants to construct expressions, or be employed by eval() function to generate expressions dynamically as needed.

5.2.1 Macro

A macro in esProc refers to a string for forming an expression, but usually this string is generated dynamically. Generally macros are values of parameters or results of expressions. In practical use, a macro should be enclosed by the sign ${}. esProc will first compute the expression enclosed by ${…} and then replace ${} with the result which is the macro string value. For example:

 

A

B

1

[+,-,*,/]

=A1(rand(4)+1)

2

=rand(1000)

=rand(1000)

3

=A2${B1}B2

 

B1 gets an arithmetic operator randomly from the list of operators in A1. A2 and B2 generate two random integers less than 1,000 and A3 performs an arithmetic operation. Results of B1, A2 and B2:

  

So, what A3 gets is the result of computing 236-393:

Here ${B1} is a macro used to construct an expression dynamically with different signs.

But if a macro is used in a string enclosed by double quotation marks, the value replacement won’t happen. For example:

 

A

B

1

A"+"A

"

2

="aabb${A1}ccdd"

 

3

=${B1}aabb${A1}ccdd"

 

${A1} in A2 won’t get assigned, and A2’s result is still the string in quotation marks:

While in A3 the left double quotation mark is changed to a macro. Now the two macros are outside quotation marks and are validated, thus can be used to construct the expression ="aabbA"+"Accdd". After computation A3 gets the following result:

It can be seen from the above illustration that, different from string parameters, a macro is a part of an expression and used for dynamically generating an expression.

Macros are often used to dynamically call cell values and functions using names, and dynamically use parameters. They are convenient to use because the mentioned requirements are difficult to be realized using fixed expressions. For example:

 

A

B

1

4779736

AL

2

710231

AK

3

6392017

AZ

4

2915918

AR

5

37253956

CA

6

=[A1:A5].pselect(~>5000000)

 

7

=B${string(A6)}

 

A6 finds the row containing the first-found data item where the population is greater than5,000,000. According to the row number, A7’s expression finds the the corresponding cell in column B so as to get the state abbreviation. Note that the expression in the macro must return a string. Therefore, string() function is needed in A7 to convert the row number obtained by A6 into a string when the macro is used to generate a cell name. Results of A6 and A7 are as follows:

 

Also note that a macro in a cell will be parsed only in its first use. Therefore macros are not suitable for a loop operation. For example:

 

A

B

1

4779736

AL

2

710231

AK

3

6392017

AZ

4

2915918

AR

5

37253956

CA

6

=[A1:A5].pselect@a(~>5000000)

 

7

=A6.(B${string(A6.~)})

 

Here A6 returns all rows containing data items where the population is greater than 5,000,000:

A7 loops over the A6’s sequence to try to get the corresponding state abbreviation. Here’s the result:

As the string in the macro is only get assigned when the expression is first parsed, both state abbreviations obtained are AZ, which is the result when the macro’s value is first replaced.

It should be made clear that macros are used for generating expressions, not for generating command statements, like for statement and func function.

5.2.2 eval function

esProc eval(x, …) function can convert the string obtained by computing x into an expression and compute its value. Similar to a macro, the function also generates an expression. But the difference lies that a macro only converts a pat of the expression while eval function generates a new expression in which parameters are allowed and return its result.

Since eval function should generate an expression when computed, the result of expression x must be a string. For example:

 

A

B

1

[+,-,*,/]

=A1(rand(4)+1)

2

=rand(1000)

=rand(1000)

3

=eval("A2"+B1+"B2")

 

An arithmetic expression is generated randomly and then computed in A3.

Here’re results of B1, A2 and B2:

  

A3 shows the different use of eval() function from that of the macro. The result of A3 is that of computing 893+466:

The eval function is more powerful than the macro. It can achieve the functionality similar to a self-defining function has when using parameters in the to-be-calculated expression. For example:

 

A

1

=eval("?.count(~>5)",[2,3,4,5,6,7,8])

2

=eval("if (?1>0 && ?2>0 && ?3>0 && ?1+?2>?3 && ?1+?3>?2 && ?2+?3>?1)",3,2,5)

A1 calculates the number of members that are greater than 5 in a sequence using eval function. The question mark ? in the expression used in the function is a parameter. A2 checks if the three parameters qualify as the lengths of the three sides of a triangle. ?1, ?2 and ?3 respectively match the first, the second and the third parameter. Here’re results of A1 and A2:

  

In the eval function, the expression will be parsed each time it is computed, so it can be used for loop operations. For example:

 

A

B

1

4779736

AL

2

710231

AK

3

6392017

AZ

4

2915918

AR

5

37253956

CA

6

=[A1:A5].pselect@a(~>5000000)

 

7

=A6.(eval("B"+string(A6.~)))

 

Now A7 gets the expected result:

5.2.3 String constants

The string constants we’re going to talk about are neither the strings simply enclosed by double quotation marks, nor the string-type constants, they are the strings represented by the format of $[…]. $[…] and "…" have similar uses. Both of them stand for the string represented by … in an expression. For example:

 

A

1

="abc"+$[ABC]

2

="\"[abc]\""+$["[ABC\]"]

Here’re results of A1and A2:

 

It can be seen that $[…] and "…" have basically the same use. Strings enclosed by both of them use a backslash \ as the escape character to interpret ambiguous characters literally, like the quotation mark " used in an ordinary string and the right bracket ] in a common string constant.

In fact, the string constant in the format of $[…] is often used in a macro or the eval function. In the esProc IDE, the cell name in the expression in $[…] will automatically adjust itself during editing, and the expression will be automatically adjusted during copy and paste operations. Thus when a string constant needs to return a cell name, these features prevent expression errors if there is any change in cellset structure. For example:

 

A

B

1

select * from STATES

=demo.query(A1)

2

POPULATION>10000000

=demo.query($[${A1} where ${A2}])

3

left(ABBR,1)='C'

=demo.query($[${A1} where ${A2} and ${A3}])

Both B2 and B3 generate a query string for the query function with cell values by using macros within a string constant. B2 queries states whose population is greater than 10,000,000:

B3 finds states whose population is greater than 10,000,000 and whose abbreviations begin with letter C:

Now if an empty row is inserted before the second row, the cellset will be like this:

 

A

B

1

select * from STATES

=demo.query(A1)

2

 

 

3

POPULATION>10000000

=demo.query($[${A1} where ${A3])

4

left(ABBR,1)='C'

=demo.query($[${A1} where ${A3} and ${A4}])

It can be seen that the cell names in expressions in both B3 and B4 change accordingly. As a string represented by "…" cannot use macros, and the content of "…" will not change along with the editing, the format is not applicable in certain cases.