Powershell - declaring array of arrays is not so easy? [duplicate] - arrays

This question already has answers here:
PowerShell enumerate an array that contains only one inner array
(2 answers)
Closed 2 years ago.
I tried to describe a small 'list' of things, using arrays of arrays. An odd behaviour I observed:
function write-it-out([array] $arrays)
{
foreach($a in $arrays)
{
write-host "items" $a[0] $a[1]
}
}
$arrayOfArrays1 = #(
#("apple","orange"),
#("monkey","bear")
)
$arrayOfArrays2 = #(
#("android","linux")
)
# it works
write-it-out $arrayOfArrays1
# it wont
write-it-out $arrayOfArrays2
The first case outputs the expected two lines with the following content:
items apple orange
items monkey bear
But the second function call outputs not the expecteds
items android linux
but
items a n
items l i
Does somebody know why? And how to describe an array containing only one array inside, not more than one? So how to fix it? Thank guys in advance!

I'm not exactly sure why, but when you declare $arrayOfArrays2, PowerShell is immediately unrolling the outer array.
> $arrayOfArrays2.Count
2
> $arrayOfArrays2[0]
android
In order to make it not do that, you can add an extra comma inside the outer array declaration like this.
> $arrayOfArrays2 = #(,#("android","linux"))
> $arrayOfArrays2.Count
1
> $arrayOfArrays2[0]
android
linux
> write-it-out $arrayOfArrays2
Items android linux

Related

Group similar element of array together to use in foreach at once in perl

i have an array which contents elements in which some elements are similiar under certain conditions (if we detete the "n and p" from the array element then the similiar element can be recognised) . I want to use these similiar element at once while using foreach statement. The array is seen below
my #array = qw(abc_n abc_p gg_n gg_p munday_n_xy munday_p_xy soc_n soc_p);
Order of the array element need not to be in this way always.
i am editing this question again. Sorry if i am not able to deliver the question properly. I have to print a string multiple times in the file with the variable present in the above array . I am just trying to make you understand the question through below code, the below code is not right in any sense .... i m just using it to make you understand my question.
open (FILE, ">" , "test.v");
foreach my $xy (#array){
print FILE "DUF A1 (.pin1($1), .pin2($2));" ; // $1 And $2 is just used to explain that
} // i just want to print abc_n and abc_p in one iteration of foreach loop and followed by other pairs in successive loops respectively
close (FILE);
The result i want to print is as follows:
DUF A1 ( .pin1(abc_n), .pin2(abc_p));
DUF A1 ( .pin1(gg_n), .pin2(gg_p));
DUF A1 ( .pin1(munday_n_xy), .pin2(munday_p_xy));
DUF A1 ( .pin1(soc_n), .pin2(soc_p));
The scripting language used is perl . Your help is really appreciated .
Thank You.!!
Partitioning a data set depends entirely on how data are "similiar under certain conditions."
The condition given is that with removal of _n and _p the "similar" elements become equal (I assume that underscore; the OP says n and p). In such a case one can do
use warnings;
use strict;
use feature 'say';
my #data = qw(abc_n abc_p gg_n gg_p munday_n_xy munday_p_xy soc_n soc_p);
my %part;
for my $elem (#data) {
push #{ $part{ $elem =~ s/_(?:n|p)//r } }, $elem;
}
say "$_ => #{$part{$_}}" for keys %part;
The grouped "similar" strings are printed as a demo since I don't understand the logic of the shown output. Please build your output strings as desired.
If this is it and there'll be no more input to process later in code, nor will there be a need to refer to those common factors, then you may want the groups in an array
my #groups = values %part;
If needed throw in a suitable sorting when writing the array, sort { ... } values %part.
For more fluid and less determined "similarity" try "fuzzy matching;" here is one example.

Python numpy: Selecting array entries based on input array [duplicate]

This question already has answers here:
Getting the indices of several elements in a NumPy array at once
(5 answers)
Closed 2 years ago.
Assume I have an array:
a = np.array([1,2,3,4,5])
Now I want to find the indices of elements in this array corresponding to the values given by another array input:
input = np.array([2,4,5])
The expected result should be:
result = [1,3,4]
A boolean mask, which is true for element indices 1,3,4 would also be fine.
I do not want to use looping to solve this. I assume that a possible solution has to do with the numpy where() function, but using this one, I am only able to compare the entries of array a with one element of array input at a time. Because the length of input might differ, I cannot really use this approach. Do you have any other ideas?
Thanks in advance.
np.where(np.in1d(a, inp))[0]
or:
np.isin(a, inp).nonzero()[0]
or as suggested here:
sorter = np.argsort(a)
sorter[np.searchsorted(a, inp, sorter=sorter)]
output:
[1 3 4]
np.where(np.in1d(a, inp))[0] np.where(np.in1d(a, inp))[0]

Unexpected array size [duplicate]

This question already has an answer here:
Powershell Join-Path showing 2 dirs in result instead of 1 - accidental script/function output
(1 answer)
Closed 3 years ago.
I'm trying to make a simple blackjack game as a Powershell script and found out that my ArrayList is not behaving as expected. I want to understand why I get a different answer then expected.
The Write-Host $deck call inside the function prints out the deck as I expect, 52 objects. So far so good.
However, when calling Write-Host $myDeck the weird part begins. What it will do is, it will first print 0...51 and then my actual deck. So instead of having 52 objects in my ArrayList I get 104 (52+52). Can anyone explain what really happens here? Because I find this super confusing.
function Get-Deck(){
$ranks = 2,3,4,5,6,7,8,9,10,"Jack","Queen","King","Ace"
$suits = "Spade","Heart","Diamond","Club"
$deck = [System.Collections.ArrayList]::new()
foreach($rank in $ranks){
foreach($suit in $suits){
$card = $rank , $suit
$deck.Add($card)
}
}
Write-Host $deck #prints out the actual array with 52 cards.
return $deck
}
$myDeck = Get-Deck
Write-Host $myDeck #prints out: 0 1 2 3 4 5 6 7 ... 51 2 Spade 2 Heart 2 Diamond ... Ace Club
The unexpected ouptut is caused by ArrayList.Add(). The function prototype is like so,
public virtual int Add (object value);
Note that it's got a non-void return type, int which is the ArrayList index at which the value has been added.
When $deck.Add($card) is called, the return value is left lingering on the pipeline and ends up in the arraylist. To fix the issue, either assigning the return value into an explicit variable, pass to null or cast as void. There are a few gotchas, see another an answer about those. Any of these should work. Like so,
$null = $deck.Add($card) # Preferred, (ab)uses automatic variable
[void]$deck.Add($card) # Works too
$deck.Add($card) | out-null # Works, but is the slowest option
$foo = $deck.Add($card) # Use this if you need the index value

how to generate a new array in perl each time a loop runs [duplicate]

This question already has answers here:
Creating arrays dynamically in Perl
(4 answers)
Closed 6 years ago.
I am running a loop and each time i need to store some information in a new array. How to generate a new array each time the loop runs like #array1, #array2 , #array3 and so on?
What you want is an array of arrays, i.e. a multi-dimensional array.
my #arrays;
for my $i(0..10)
{
$arrays[$i] = ['data1', 'data2'];
}
print $arrays[0][0];
print $arrays[0][1];

Bash: Can an array hold the name of another array?

I am writing a program and trying to break up data, which is stored in an array, in order to make it run faster.
I am attempting to go about it this way:
data_to_analyze=(1 2 3 4 5 6 7 8 9 10)
#original array size
dataSize=(${#data_to_analyze[#]})
#half of that size
let samSmall="$dataSize/2"
#the other half
let samSmall2=("$dataSize - $samSmall -1")
#the first half
smallArray=("${data_to_analyze[#]:0:$samSmall}")
#the rest
smallArray2=("${data_to_analyze[#]:$samSmall:$samSmall2}")
#an array of names(which correspond to arrays)
combArray=(smallArray smallArray2)
sizeComb=(${#combArray[#]})
#for the length of the new array
for ((i=0; i<= $sizeComb ; i++)); do
#through first set of data and then loop back around for the second arrays data?
for sample_name in ${combArray[i]}; do
command
wait
command
wait
done
What I imagine this does is gives only the first array of data to the for loop at first. When the first array is done it should go through again with the second array set.
That leaves me with two questions. Is combArray really passing the two smaller arrays? And is there a better way?
You can make a string that looks like an array reference then use it to indirectly access the elements of the referenced array. It even works for elements that contain spaces!
combArray=(smallArray smallArray2)
for array in "${combArray[#]}"
do
indirect=$array[#] # make a string that sort of looks like an array reference
for element in "${!indirect}"
do
echo "Element: $element"
done
done
#!/bin/bash
data_to_analyze=(1 2 3 4 5 6 7 8 9 10)
dataSize=${#data_to_analyze[#]}
((samSmall=dataSize/2,samSmall2=dataSize-samSmall))
smallArray=("${data_to_analyze[#]:0:$samSmall}")
smallArray2=("${data_to_analyze[#]:$samSmall:$samSmall2}")
combArray=(smallArray smallArray2)
sizeComb=${#combArray[#]}
for ((i=0;i<$sizeComb;i++));do
eval 'a=("${'${combArray[i]}'[#]}")'
for sample_name in "${a[#]}";do
...
done
done
EDIT: removed the double quotes near ${combArray[i]} and replaced <= by < in for

Resources