So, I know you can navigate through a 2D array with something like
arr1.each do |a1|
a1.each do |a2|
puts a2
however what I am trying to do is a little different. I have 2 sets of values stored in arrays and I want to be able to cycle through them and populate a dropdown menu from the information.
So I have data like:
names = ["bob", "frank", "tim"]
id = [1, 2, 3]
which gets returned in an array from a method like this:
def method_name
#stuff
return names, id
end
What I want to be able to do in the view is pair the corresponding indexes with each other. So, for the above example, bob-1 frank-2 tim-3 I can't seem to figure it out. I have tried slicing and nested loops and have also tried with a hash being returned instead of an array. I'm lost.
If anyone has any information on how to pull the information the way I am trying to do it, or another simpler way to do it I would really appreciate the input.
names.zip(id).map { |e| e.join('-') }
zip combines the two arrays into an array of arrays like this:
[['bob', 1], ['frank', 2], ['tim', 3]]
map loops through each of 3 elements of the outer array and converts each inner array into a string by joining its two elements together with a dash using join.
See zip, map, and join documentation.
Generally speaking, when researching array manipulation in Ruby, you'll want to look at the docs both for Array and the docs for Enumerable.
This is a rare case in Ruby where iterating on the index is helpful:
(0...names.size).map do |idx|
"#{names[idx]}-#{id[idx]}"
end
Related
I am a newbie in using pytables.
I am trying to access an array stored in a hdf5-file.
For instance the array has the dimensions 100x2000x5000, Now, I am trying to access only the first 100 data entries along the dimensions 2 and 3, something like "[:,0,0]".
But in the documentation of pytables I only find the following example:
import tables
h5file = tables.open_file('file.h5', 'r')
data = h5file.root.array.read()
h5file.close()
How I can tell the read-module only to load a subset of the array?
Thanks in advance for any help!
You can use any of the following methods to read a subset of the array. All methods return data as an object of the current flavor (same dtype as Array).
array0 = Array.read(start=None, stop=None, step=None)
You can also use NumPy-style slicing.
NumPy-style point and boolean selections are supported as well as
fancy indexing. [The latter uses a list of indices in a certain axis is specified.]
Examples below.
array1 = array[0:4] # simple selection
array2 = array[:,0] # slice selection
array3 = array[1, ::2, 1:4] # general slice selection
Specific to your request, you can use the following. (It reads the first 100 data entries along the 2nd and 3rd indices, which are axis 1 and axis 2):
your_slice = h5file.root.array[:,0:100,0:100] # slice selection
I have a 2-d array in numpy. I wish to obtain unique values only in a particular column.
import numpy as np
data = np.genfromtxt('somecsvfile',dtype='str',delimiter=',')
#data looks like
[a,b,c,d,e,f,g],
[e,f,z,u,e,n,c],
...
[g,f,z,u,a,v,b]
Using numpy/scipy only, how do I obtain an array or list of unique values in the 5th column. (I know it can easily be done with pandas.)
The expected output would be 2 values: [e,a]
Correct answer posted. A simple referencing question in essence.
np.unique(data[:, 4])
With thanks.
I know array reference, but in Perl multidimensional array is a one dimensional array of reference to other one-dimensional array can anyone explain this with an example?
my #a = ( "a", "b", "c" );
my #x;
$x[4] = \#a;
say $x[4]->[2]; # c
The dereference (->) is implied "between indexes" if omitted.
my #a = ( "a", "b", "c" );
my #x;
$x[4] = \#a;
say $x[4][2]; # c
As you can see, this can be used to create multi-dimensional arrays.
An anonymous array is commonly used. [ ... ] constructs an array and returns a reference to it.
my #x;
$x[4] = [ "a", "b", "c" ];
say $x[4][2]; # c
Also common is to let Perl create the array and the reference for you automatically through a feature called "autovivification".
my #x;
$x[4][2] = "c";
say $x[4][2]; # c
That's because
$x[4][2] = "c";
is short for
$x[4]->[2] = "c";
and
SCALAR->[EXPR1] = EXPR2;
is effectively
( SCALAR //= [ ] )->[EXPR1] = EXPR2;
so
$x[4]->[2] = "c";
is effectively
( $x[4] //= [ ] )->[2] = "c";
There are different uses of "dimension" at play here, and I recently was working in a language that used the other one. That messed me up for a moment while I had to switch thinking.
In some domains, the "dimension" is the number of elements. In others, it's the number of things you have to specify to get to an element. Some uses use the term incorrectly (or sloppily). This is incredibly reductive, but I think that's the spirit. This means, though, that you can't transfer what you know about "dimension" from one use to another use. You have to know what the particular tool thinks it means.
Simple math
Forget about programming for a moment and think about simple math, which I'll also crudely simplify.
A point (vector, whatever) with just an x and a y coordinate, say (1,2), is two dimensional because there are two things you need to specify it completely. A point with (x,y,z) is three dimensional, and so on, up to whatever multiple you like. This sort of use is a bit sloppy because a point with three coordinates is still a point (a one dimensional thing) even if it lives is a three dimensional space. But, through a bit of synedoche that's how people talk.
Then consider matrices. These have rows and columns. The rows have a certain number of thingys and the columns have a certain number of thingys. The dimension of the matrix is a combination of the number of rows and columns (there's a bit more to it, but ignore that). Someone might say they have a "three by three matrix".
Perl's use of "multi" tends more to the matrix idea.
Matrices in Perl
Perl basically has three major built-in data types (there are a few others that aren't important here). You have scalars, which are single things, lists, which are zero of more scalars, and hashes. Perl doesn't get much more complicated than that. Somehow, we have to use that simple foundation to make fancier things:
Since Perl does not have a matrix type, we fake it with anonymous arrays (see the perl data structures cookbook and Perl list of lists). A reference is single thingy, so a scalar.
my $ref = [ # top level
[ 0, 1, 2 ], # first row
[ 3, 4, 5 ], # second row
[ 6, 7, 8 ], # third row
];
Inside that top level array reference, there are three elements that are each anonymous arrays themselves. Think of those as rows. The particular position in each row is like a column. To get to any particular spot, we specify the (zero-based) row and column number:
$ref->[2][2];
That use of multiple subscripts to address any particular element gives us the "multi" in Perl. That's just how Perl uses the term, right or wrong and despite how it's used any other place.
So, finally to your question about an array ref holding a single array ref of one item:
my $ref = [ # top level
[ 'Camel' ], # first row
];
Having one row and one column is as correct as any other number or rows and columns. To get to that element, we still need to specify the row and column. They both happen to be 0.
$ref->[0][0];
And, finally, we have the trivial case of no rows or columns:
my $ref = [];
Remember though, that Perl never fixes the sizes here. It's happy to give you undef for any element you ask for:
my $value = $ref->[999][999];
And if you assign to any index higher than what it already has, it creates all the elements it needs to it can have that index. This one assignment gets you a 1000 by 1000 "matrix":
$ref->[999][999] = 'Hello';
Just for fun
The references are a Perl 5 feature, but multi-dimensional things go back to at least Perl 3. We used to fake multi-dimensional thingys with goofy hash keys. We'd separate the indices with , (or whatever the value of $; was:
$some_hash{1,3,7} = 'foo';
This was the same as:
$key = join $;, 1, 3, 7;
$some_hash{$key}
As long as your sub-keys didn't have the value of $; in them, this worked out.
This still exists in Perl, but starting with v5.36 (the latest as I write this), it's turned off:
use v5.36; # no multidimensional
Or you can turn it off:
no multidimensional;
If you really need it and still want to require a minimum of v5.36, you can re-enable it:
use v5.36;
use multidimensional;
Or, use require which doesn't do the feature stuff (but then you have to figure out what else you aren't getting but may want):
require v5.36;
After reading this I wrote a naive attempt to produce this
col1
---------
1
4
7
from this
ARRAY[[1,2,3], [4,5,6], [7,8,9]]
This works
SELECT unnest((ARRAY[[1,2,3], [4,5,6], [7,8,9]])[1:3][1:1]);
But I in my case, I don't know the length of the outer array.
So is there a way to hack together the slice "string" to take into account this variability?
Here was my attempt. I know, it's a bit funny
_ids := _ids_2D[('1:' || array_length(_ids_2D, 1)::text)::int][1:1];
As you can see, I just want to create the effect of [1:n]. Obviously '1:3' ain't going to parse nicely into what the array slice needs.
I could obviously use something like the unnest_2d_1d Erwin mentions in the answer linked above, but hoping for something more elegant.
If you are trying to get the first element of all nested (2nd dimension) arrays inside an array (1st dimension) then you may use
array_upper(anyarray, 1)
to get all elements of a specific dimension
anyarray[1:array_upper(anyarray, 1)][<dimension num>:<dimension num>]
e.g, to get all elements of the first dimension
anyarray[1:array_upper(anyarray, 1)][1:1]
as in the code above. Please refer to PostgreSQL manual section on Arrays for more information.
I'v multiple arrays of [1x3], however I named them array1 array2 array3 and so on. What I want to create one array from all arrays such that array=array1(i,1:3) array=array2(i,4:6) and so on. How I can done this by looping or any suggestions regarding my approach, I actually want to access multiple arrays dynamic so that I'm going with this approach, any other suggestions are welcomed as I thought there will be slow computations and processing speed when my array size increases.
My Code:
for i=1:10
array(i)=array(:,i:i+3);
end
The easiest way is use cat function:
array = cat(2,array_1,array_2,array_3);
If you want to access array_i (i=1,2,3,...)
array_i = array((i-1)*3+1:i*3);
The jth index (j=1,2,3) of the array_i (i=1,2,3,4,...) can be accessed:
jth_index_of_array_i = array((i-1)*3+j)