Perl dereferencing array for specific value - perl

So, in Perl, I have an array within an object (so, a reference to an array), and I want to find the first value of that array.
I find myself using code like the following quite often:
my $server_ref = $self->{source_env}->{server};
my #servers = #$server_ref;
my $main_server = $servers[0];
That works, but I'm sure I could do this without all the intermediate lines and variables.
Can someone help me with the syntax?

Try:
my $main_server = $self->{source_env}->{server}->[0];

Try $server_ref->[0], it should work.

Related

Which alias module better to use?

I want to alias values from source array to hash values
#$data{ $sth->{NAME_lc}->#* } = $self->source->#*;
What is the best way to accomplish this task?
UPD
Here I want hash value refer to array value. And if hash value is changed the corresponding value in array must be changed too
I have found this solution:
use Data::Alias;
alias #$data{ $sth->{NAME_lc}->#* } = $self->source->#*;
UPD
Thanks #amon for refaliasinglists:
\(#$data{ $sth->{NAME_lc}->#* }) = \($self->source->#*)
UPD
Seems last examples does not work. Aliases are lexically scoped. reported as RT#133538
Data::Alias still works fine
UPD
Data::Alias is most ++ aliasing module on metacpan.org so I think it is the best method as of today. Until refaliasing feature will be fixed.

How to apply the result and index of the result of max() to an array on a single line

I was given a problem in MatLab where I needed to write a single line of code that starts with
variableName =
and find the max value of a 2d array and it's index. I don't use matlab at all, and this seems infuriatingly simple in any language I know. I know to get the value & index of the result of max, you do something like
[M,I] = max(stuffToCheck)
I just dont understand how to assign the array that creates to a variable name. I've spent some time googling but this feels like a very weird constraint so I haven't found anything yet. How do I do this on one line?
use the variable you want to assign the result:
[variableName(:,1),variableName(:,2)] = max(stuffToCheck)
its the only way because in matlab if you write :
variable = function();
matlab return only the first output, to get other ouput you have to write:
[output1,output2,...] = function();

Avoiding eval in assigning data to struct array

I have a struct array called AnalysisResults, that may contain any MATLAB datatypes, including other struct arrays and cell arrays.
Then I have a string called IndexString, which is the index to a specific subfield of StructArray, and it may contain several indices to different struct arrays and cell arrays, for example:
'SubjectData(5).fmriSessions{2}.Stats' or 'SubjectData(14).TestResults.Test1.Factor{4}.Subfactor{3}'.
And then I have a variable called DataToBeEntered, which can be of any MATLAB datatype, usually some kind of struct array, cell array or matrix.
Using eval, it is easy to enter the data to the field or cell indexed by IndexString:
eval([ 'AnalysisResults.', IndexString, ' = DataToBeEntered;' ])
But is it possible to avoid using eval in this? setfield doesn't work for this.
Thank you :)
Well, eval surely is the easiest way, but also the dirtiest.
The "right" way to do so, I guess, would be to use subsasgn. You will have to parse the partial MATLAB command (e.g. SubjectData(5).fmriSessions{2}.Stats) into the proper representation for those functions. Part of the work can be done by substruct, but that is the lightest part.
So for example, SubjectData(5).fmriSessions{2}.Stats would need to be translated into
indexes = {'.' , 'SubjectData',
'()', {5},
'.' , 'fmriSessions',
'{}', {2},
'.' , 'Stats'};
indexStruct = substruct(indexes{:});
AnalysisResult = subsasgn(AnalysisResult, indexStruct, DataToBeEntered);
Where you have to develop the code such that the cell array indexes is made as above. It shouldn't be that hard, but it isn't trivial either. Last year I ported some eval-heavy code with similar purpose and it seemed easy, but it is quite hard to get everything exactly right.
You can use dynamic field names:
someStruct.(someField) = DataToBeEntered;
where someField is a variable holding the field name, but you will have to parse your IndexString to single field name and indices.

Simplify CoffeeScript statement

I am trying to handle a simple case where i could be getting an object, or a dictionary. So i am either going to get a object like:
obj.fields.nick
or its going to be a dictionary like
obj['nick']
I was wondering if there was a simpler way to do the following:
value = (eval("obj.fields." + field[1]) if obj?.fields ) ? eval("obj['#{field[1]}']")
I was hoping to do something like:
value = (obj?.fields?."#{field[1]}" ) ? eval("obj['#{field[1]}']")
But if that worked I wouldn't be writing this post...
I am basically looking for a way to execute a string as part of the if
value = obj.fields?[field] ? obj[field]
# or
value = (obj.fields ? obj)[field]
This is the same as
if obj.fields?
obj.fields[field]
else
obj[field]
There is absolutely no need for eval.
The string interpolation construct ("Equals four: #{2+2}") is something that is handled by the coffeescript compiler, and will therefore not work inside an eval. But assuming the naming of the stuff inside the string does not change, you could easily rewrite it, so that eval("obj['#{field[1]}']") becomes eval("obj['"+field[1]+"']"). Assuming I got your question right of course.

How to create an ArrayList from an Array in PowerShell?

I've got a list of files in an array. I want to enumerate those files, and remove specific files from it. Obviously I can't remove items from an array, so I want to use an ArrayList.
But the following doesn't work for me:
$temp = Get-ResourceFiles
$resourceFiles = New-Object System.Collections.ArrayList($temp)
Where $temp is an Array.
How can I achieve that?
I can't get that constructor to work either. This however seems to work:
# $temp = Get-ResourceFiles
$resourceFiles = New-Object System.Collections.ArrayList($null)
$resourceFiles.AddRange($temp)
You can also pass an integer in the constructor to set an initial capacity.
What do you mean when you say you want to enumerate the files? Why can't you just filter the wanted values into a fresh array?
Edit:
It seems that you can use the array constructor like this:
$resourceFiles = New-Object System.Collections.ArrayList(,$someArray)
Note the comma. I believe what is happening is that when you call a .NET method, you always pass parameters as an array. PowerShell unpacks that array and passes it to the method as separate parameters. In this case, we don't want PowerShell to unpack the array; we want to pass the array as a single unit. Now, the comma operator creates arrays. So PowerShell unpacks the array, then we create the array again with the comma operator. I think that is what is going on.
Probably the shortest version:
[System.Collections.ArrayList]$someArray
It is also faster because it does not call relatively expensive New-Object.