Perl : map statement - perl

I would like your help, because I am not able to understand what the following line means:
map {#$_[1 .. 4]} #msft
found in the example code of GD::Graph::ohlc.
Could you please provide me with a hint?
Thank you.

#msft is an array of arrays where each inner array contains 5 items (date, open/low/high/close prices).
The map takes each element of #msft, which is an array reference stored in $_ and dereferences it via #$_ and takes a slice of that array (namely the second through fifth items since the array is 0-based) via the [1..4]. It then returns those four items. map concatenates them into a single list.
In essence, it is flattening the array of arrays of five elements into a single array made up of the 2nd through 5th items of each subarray.

The elements of #msft are array references. The code collects elements 1 through 4 from each array into a single list:
my #msft = (
[0,1,2,3,4,5],
[0,11,22,33,44,55],
[0,111,222,333,444,555],
);
my #result = map {#$_[1 .. 4]} #msft;
print "#result\n"; # 1 2 3 4 11 22 33 44 111 222 333 444
From the documentation for map:
Evaluates the BLOCK or EXPR for each
element of LIST (locally setting $_ to
each element) and returns the list
value composed of the results of each
such evaluation.

Related

KDB+/Q : How does the following code work ? q) 16 16#"c"$til 256`

How does the following code work in kdb+/q , specifically, what does the first 16 do ?
q)16 16#"c"$til 256
til 256 creates a list 0 .. 255, "c"$ casts each entry to type char, and 16#takes the first 16 elements, but what does the first 16 do ?
I cannot see this mentioned anywhere in the documentation, despite this being an example quoted here: https://code.kx.com/q4m3/4_Operators/#433-order
# operator will select leading or trailing items from a list or dictionary
x#y #[x;y]
Where x is an int atom or vector, or a table; y is an atom, list, dictionary, table, or keyed table
In your case x is a vector and returns a matrix or higher-dimensional array, for example
q)2 4#`Arthur`Steve`Dennis
Arthur Steve Dennis Arthur
Steve Dennis Arthur Steve**
By splitting up your example you can see the first and last lines returned from the array
q)16#"c"$til 256
"\000\001\002\003\004\005\006\007\010\t\n\013\014\r\016\017"
q)-16#"c"$til 256
"\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377"
For more information
https://code.kx.com/q/ref/take/

Comma Before Parentheses in Variable Assignment

I'm using the S.DS.P PowerShell module in a PowerShell script of mine. In it, I have to create the following object:
$ADUserEntry = #{"distinguishedName"=$null;"objectClass"=$null;"sAMAccountName"=$null;"unicodePwd"=$null;"userAccountControl"=0};
In the documentation of the module, it's stated that I have to do the following assignment to the unicodePwd field of a variable created using this object:
$obj.unicodePwd = ,([System.Text.Encoding]::Unicode.GetBytes("$randomPassword") -as [byte[]]);
Notice how there's a comma before the first parentheses. What is that comma doing there?
As Lee_Dailey has pointed out, what you're seeing is the unary form of the (unfortunately named) "comma operator", i.e., PowerShell's array-construction operator.
The unary form creates a single-element array that wraps its (one and only) operand; the array's type is [object[]], as usual in PowerShell:
$arr = , 'foo' # wrap string 'foo' in a single-element array
$arr.GetType().Name # the array's type -> 'Object[]'
$arr[0].GetType().Name # the type of the array's one and only element -> 'String'
Note that while you can even wrap arrays that way, PowerShell's operator-precedence rules require a literal array operand to be enclosed in (...):
# OK - wraps array 1, 2 in a single-element array.
$arr = , (1, 2)
# !! DOES SOMETHING DIFFERENT:
# Creates a 2-element array whose 1st element is integer 1 wrapped in a
# single-element array
$arr = , 1, 2
The binary form constructs an array from the operands, as expected:
$arr = 1, 2, 3 # 3-element array whose elements are integers 1 and 2 and 3
As an aside, re the specific command shown:
,([System.Text.Encoding]::Unicode.GetBytes("$randomPassword") -as [byte[]])
Neither , nor -as [byte[]] are needed in this scenario, because
[System.Text.Encoding]::Unicode.GetBytes() directly returns a [byte[]] array.

error in number of input argument

I have a 99*1 symbolic expression array.it has 676 variables that I stored them in 'varsubs'
I convert it to function with
cccc = matlabFunction(sloads , 'vars' , varsubs)
I check the number of input arguments with
nargin(cccc)
and matlab return 676.
after that for test the cccc function I created an array
xxxx = ones(1,676)
and the substitute that in cccc
cccc(xxxx)
but I got an error
**Error using
Not enough input arguments.**
Who knows why this error happend ?
xxxx is a single array with 676 elements, so you're only actually passing 1 argument. I'm really not sure what exactly you're trying to do but if you really want to pass 676 arguments all equal to one then you need to generated a comma separated list by calling {:} on a cell array whose elements are all equal to 1:
xxxx{676} = [];
[xxxx{:}] = deal(1);
cccc(xxxx{:})

What does this mean in Perl 1..$#something?

I have a loop for example :
for my $something ( #place[1..$#thing] ) {
}
I don't get this statement 1..$#thing
I know that # is for comments but my IDE doesn't color #thing as comment. Or is it really just a comment for someone to know that what is in "$" is "thing" ? And if it's a comment why was the rest of the line not commented out like ] ) { ?
If it has other meanings, i will like to know. Sorry if my question sounds odd, i am just new to perl and perplexed by such an expression.
The $# is the syntax for getting the highest index of the array in question, so $#thing is the highest index of the array #thing. This is documented in perldoc perldata
.. is the range operator, and 1 .. $#thing means a list of numbers, from 1 to whatever the highest index of #thing is.
Using this list inside array brackets with the # sigill denotes that this is an array slice, which is to say, a selected number of elements in the #place array.
So assuming the following:
my #thing = qw(foo bar baz);
my #place = qw(home work restaurant gym);
then #place[1 .. $#thing] (or 1 .. 2) would expand into the list work, restaurant.
It is correct that # is used for comments, but not in this case.
it's how you define a range. From starting value to some other value.
for my $something ( #place[1..3] ) {
# Takes the first three elements
}
Binary ".." is the range operator, which is really two different
operators depending on the context. In list context, it returns a list
of values counting (up by ones) from the left value to the right
value. If the left value is greater than the right value then it
returns the empty list. The range operator is useful for writing
foreach (1..10) loops and for doing slice operations on arrays. In the
current implementation, no temporary array is created when the range
operator is used as the expression in foreach loops, but older
versions of Perl might burn a lot of memory when you write something
like this:
http://perldoc.perl.org/perlop.html#Range-Operators

join() function is returning the type followed by a hex number instead of a concatenated string

In essence, I want to take an array and create a single string with the elements of said array separated by a newline.
I have an array named $zones. Outputting the reference to $zones confirms it's an array.
The following code:
print_log(Dumper($zones));
print_log('-------');
print_log(Dumper(join("\n",$zones)));
results in the following output
[2013-06-15 16:23:29 -0500] info [dnsadmin] $VAR1 = [
'fake.com25',
'fake.com2',
'fake.com27',
'fake.com43',
'fake.com41',
'fake.com40',
'fake.com39',
'fake.com37',
'fake.com36',
'fake.com35',
'fake.com31',
'fake.com56',
'fake.com55',
'fake.com54',
'fake.com53',
'fake.com52',
'fake.com51',
'fake.com50',
'fake.com49',
'fake.com48',
'fake.com42',
'fake.com38',
'fake.com34',
'fake.com33',
'fake.com32',
'fake.com30',
'fake.com29',
'fake.com28',
'fake.com26',
'fake.com24',
'fake.com23',
'fake.com69',
'fake.com68',
'fake.com67',
'fake.com66',
'0',
'fake.com44',
'fake.com45',
'fake.com46',
'fake.com278'
];
[2013-06-15 16:23:29 -0500] info [dnsadmin] -------
[2013-06-15 16:23:29 -0500] info [dnsadmin] $VAR1 = 'ARRAY(0x170cf0d8)';
I really don't want to loop over this array manually. Can someone explain why the join() function is returning the name of the type along with a hex number?
How to do is explained well by user1937198, but why it works this way?
It's simple:
$zones is not an array. It's an array reference.
join works on lists. So if you do:
join("\n",$zones)
You essentially are calling join on a single-element list. And the element is a reference, which happens to stringify to ARRAY(0x170cf0d8).
To make it work correctly you have to dereference it, and it is done by prefixing with real datatype (# or %, or in some cases $).
This can be written like this: #$zones, or (some, including me, say that it's more readable) as: #{ $zones }.
This is important when you're having nested structures, because while you can have plain array as a variable, when you're dealing with nested data structures, it's always references.
what you want is join("\n",#{$zones}))
$zones is array reference and to join array values you have to dereference it first by prefixing scalar $zones with #
print_log(Dumper(join("\n",#$zones)));
For more info there is short tutorial on references:
http://perldoc.perl.org/perlreftut.html#NAME