Why does this not give the 2nd last element of the array? [closed] - perl

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 8 years ago.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Improve this question
print $some_array[$#some_array - 1];
My intuitive understanding is the above code should print the 2nd last element in #some_array.
However in reality it does not. It prints something I cannot made sense of.

It does print the second to last element in the array:
my #nums = qw(a b c d e);
print "$nums[$#nums-1]\n"; # prints 'd'
Here, $#nums gives the last index of an array (in this case 4 - arrays are zero-based), and hence $#nums - 1 gives array element 3.
A more common way of writing this would be:
$array[-2]

The behavior of $some_array[$#some_array - 1] depends on how many elements #some_array has.
If #some_array has 2 or more elements (scalar #array >= 2, or equivalently $#array >= 1), then your statement:
print $some_array[$#some_array - 1];
should work correctly. Say the array has 10 elements, then $#some_array == 9, and you'll print $some_array[8], the second-to-last element.
If #some_array has just one element, then $#some_array == 0, and you'll print the "-1th" element. Negative array indices are treated specially: -1 gives you the last element of the array, -2 the second-to-last, and so forth. And if your goal is to print the second-to-last element of the array, you should be using this feature.
If #some_array is empty (scalar #some_array == 0, $#some_array == -1), then your statement will try to print $some_array[-2], which doesn't exist, resulting in an error message.

Related

Powershell, what exactly does each part of this code do? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 5 years ago.
Improve this question
$a = gc "$home\documents\textfile.txt"
for ($i = 0; $i -lt $a.Count + 1; $i++)
{
$a[($a.count-1) - $i]
}
I know the first line gets the content of the text file, and the file is shown from bottom to top, but what exactly is the for loop doing step-by-step?
The for loop sets $i to 0, loops for as long as it's less than or equal to $a.Count-1 and increments after each iteration.
$a.Count is the total number of lines in the file, so $a.Count-1 is the final element (line) of $a which is an array indexed from zero.
Within each iteration $i gets larger and so the line inside the loop returns the value held at the last element minus $i.
If $a has 5 lines for example, then there are 5 elements in $a. These are $a[0] to $a[4]
On the first iteration $i is zero so the value within the square brackets evaluates to 5-1-0 = 4. This gives the last line.
On the second iteration all that changes is $i is incremented. This evaluates to 5-1-1 = 3. This is the second to last line.
This carries on until $i = 4 (which is $a.Count-1) and the code evaluates 5-1-4=0, which results in the first element of $a being output.
Hope that makes sense enough for you...
What the for loop is doing is getting the index of the string provided by $a.
You can play with indexing by setting a variable equal to a string or array, and looking at each of the indices within it. Take, for example, $x = "this is a string". You can then look at $x[n] where n is an integer, and it will show you what that index in the string or array contains. For $x[0] Powershell would return "t", or if $x were an array of strings it would return "this".
Now that we know what indexing is, we can look at the math operators within your for loop. To think about this in the way that Powershell is processing it, we'll work from the parenthesis out. $a.count returns a value equal to the number of objects contained in $a. If we look at what Get-Content returns (with help from our handy Get-Help gc), we can see that it is returning an object per line contained in that file.
When we apply these principles to the script you provided, we can determine that the script will return the lines of the file in reverse order.

"isn't numeric" warning from perl [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
Perl keeps telling me that '11' from my input file is not numeric. Last time I checked 11 was a number, so I'm a bit confused what the problem is here and hence where to start looking.
Interestingly, it's line 1 of my input file causing the problem, the numbers on lines 2 onwards are interpreted correctly.
Argument "11" isn't numeric in numeric eq (==) at ./extract.pl line 200, <INPUTFILE> line 1.
Line 200 is
if ($_data[0] == $_ch && !exists $_ch_sn{$_data[1]}) { $_ch_sn{$_data[1]} = undef; }
Any help much appreciated!
The error was caused by a BOM in my inputfile. Using setlocal nobomb in Vi solved the problem!
It could be that the source doesn't actually contain 11 (e.g. maybe it contains a character that resembles a one but isn't), but I suspect the warning message is incorrectly identifying the expression that's non-numeric[1].
That fact that nothing remotely resembling 11 appears on that line appears to support that[2].
So just pretend you obtained the following warning:
Argument isn't numeric in numeric eq (==) at ./extract.pl line 200, <INPUTFILE> line 1.
This means that $_data[0] or $_ch is a non-numeric string[2].
If both should be numbers, determine which one isn't, possibly using the following code:
use Data::Dumper; { local $Data::Dumper::Useqq = 1; warn(Dumper($_data[0], $_ch)); }
Once you determine which variable is wrong, debug to find out why it is that way.
If they could be legitimately be non-numeric, add appropriate checks to handle that situation.
For performance reasons, that part of the error message is deduced from the compiled code, a complicated and unreliable process.
I'm assuming the if has no elsif clause. Warnings from an elsif condition can appear to be from an if statement.

Print 10 elements out of array [duplicate]

This question already has answers here:
What's the best way to get the last N elements of a Perl array?
(6 answers)
Closed 7 years ago.
If i have an array that I've used to create 50 random numbers, I then sort them numerically. Now lets say I wanted to print out the 10 biggest number (elements 40 to 50) I could say:
print($array[40]) print($array[41]) print($array[42]) etc etc.
But is there a neater way to it? Hope I'm making myself clear.
Cheers
You could loop over the indexes.
say $array[$_] for 40..49;
Offsets from the end make more sense here.
say $array[$_] for -10..-1;
You could also use an array slice.
say for #array[-10..-1];
To print them on one line, you can use join.
say join ', ', #array[-10..-1];
Try this :
print join ',',#array[-10..-1] ,"\n";

Print a substring of an array value [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I have an array in the third element dataArr[2], I know it contains a 10 digit phone. I need to only read or print the first 6 digits. For instance if my phone is 8329001111, I need to print out the 832900. I tried to see if I can use substr but I keep reading or printing the full list. Do I need to dereference..
Try this :
$dataArr[2] =~ s/\s//g; # ensure there's no spaces
print substr($dataArr[2], 0, 6);
# ^ ^ ^
# variable | |
# offset start|
# |
# substring length

Comparing floating point with another number [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
How to check if one floating point number is bigger than another number in Perl?
i.e: 100.4 > 90
I tried to work with use POSIX, rounding the 100.4 to 101.0 and converting both of them with int, but Perl still thinks that my 100.4 is smaller than my 90.
Edit: The bug was somewhere else. The privious code returned me sometimes true and sometimes false.
No, Perl doesn't 'think' that, and that's easy to check:
print 100.4 > 90 ? 'Greater' : 'Lesser'; # Greater
My (wild) guess is that you've tried to sort an array of floats, and got 100.4 standing before 90. For example, like this:
my #floats = (100.4, 50, 9);
print $_, "\n" for sort #floats;
# 100.4
# 50
# 9
The catch is that by default Perl uses string comparison in sort. So both 100.4 and 90 are cast to string first, and '100.4' is indeed lesser than '9', because '1' is lesser than '9' (strings are compared char-by-char).
The solution is simple: override the sorting routine when dealing with numbers.
print $_, "\n" for sort { $a <=> $b } #floats;
# 9
# 50
# 100.4