Yii2 Array sorting - arrays

In my Yii2 Project I have an array for example
$array = [];
$array [] = 8 , 3, 6
So when I print out the array is
[8,3,6]
So when I use the same in a where statement it jumbles up.
$class = ModelClass::find()->where(['array_no' => $array])->all
So when I print out class I get the output in asc order sorted..
I get the information of
3 in the first
6 in the second place
8 in the third place.
How can i stop this from happening. I want them to return my output in the same order as array

You should use ORDER BY FIELD(), e.g. :
$models = ModelClass::find()
->where(['array_no' => $array])
->orderBy(new \yii\db\Expression('FIELD (array_no, '.implode(',', $array).')'))
->all();

Related

Why can't I push items into a hash of arrays, in Perl?

What I want here is for #{$allHash{$key1}} to be ["item1", "item2"].
Pushing doesn't work, and all the print statements are to try and find where the pushed items went.
Using -> notation in the push is even worse, it makes $temp[0][0] and line 24 show an array instead of the item.
#use strict; # I've turned these off here to make the code easier to read
#use warnings;
my %allHash = ();
my $key1 = "key1";
my $item1 = "item1";
my $item2 = "item2";
#if (!exists($allHash{key1})) {$allHash{key1}=();}; # makes no difference, the array autovivefies anyway
push (#{$allHash{$key1}}, $item1); # push 1st item
print"\n\nat11: pushed $key1, $item1";
my #temp = $allHash{$key1};
print"\nat13:temp=#temp, length=",0+#temp, ", temp[0]=$temp[0], temp[0][0]=$temp[0][0]";
print"\nat14: allHash{$key1}[0]= $allHash{$key1}[0]";
print"\nat15: allHash{$key1}[1]= $allHash{$key1}[1]";
print"\nat16: allHash{$key1}[0][0]= $allHash{$key1}[0][0]";
print"\nat17: allHash{$key1}[1][0]= $allHash{$key1}[1][0]";
print"\nat18: allHash{$key1}[0][1]= $allHash{$key1}[0][1]\n";
print"\n----------------";
push (#{$allHash{$key1}}, $item2); # push 2d item
print"\n\nat21: pushed $key1, $item2";
#temp = #{allHash{$key1}};
print"\nat23:temp=#temp, length=",0+#temp, ", temp[0]=$temp[0], temp[0][0] =$temp[0][0]";
print"\nat24: allHash{$key1}[0]= $allHash{$key1}[0]";
print"\nat25: allHash{$key1}[1]= $allHash{$key1}[1], allHash{$key1}[1][0] =$allHash{$key1}[1][0]";
print"\nat26: allHash{$key1}[0][0]= $allHash{$key1}[0][0]";
print"\nat27: allHash{$key1}[1][0]= $allHash{$key1}[1][0]";
print"\nat28: allHash{$key1}[0][1]= $allHash{$key1}[0][1]\n";
The output from the above program is:
at11: pushed key1, item1
at13:temp=, length=1, temp[0]=ARRAY(0x331eb8), temp[0][0]=item1
at14: allHash{key1}[0]=item1
at15: allHash{key1}[1]=
at16: allHash{key1}[0][0]=
at17: allHash{key1}[1][0]=
at18: allHash{key1}[0][1]=
----------------
at21: pushed key1, item2
at23:temp=ARRAY(0x331ee8), length=1, temp[0]=ARRAY(0x331ee8), temp[0][0]=item1
at24: allHash{key1}[0]=item1
at25: allHash{key1}[1]= ARRAY(0x332020), allHash{key1}[1][0]=
at26: allHash{key1}[0][0]=
at27: allHash{key1}[1][0]=
at28: allHash{key1}[0][1]=
What's bizarre is that this almost identical code from another of my programs works perfectly.
%hedgeHash = (); # collect the members of each hedge as an array, using stub as key
for (my $i=0; $i<#options; $i++)
{ $Hstub = $options[$i][$iStub];
push #{$hedgeHash{$Hstub}}, $i; # hedgehash should contain array of members of the hedge.
}
What's even more bizarre is that if I remove the parentheses from the push statement, I no longer get 'item1' as the output of #temp and on lines 14 and 24, but get another array! WTF??
Please see a sample code bellow demonstrating a use of hash of arrays.
Indeed OP's coding style makes code reading somewhat difficult.
use strict;
use warnings;
use feature 'say';
use Data::Dumper;
my %allHash;
my $key1 = 'key1';
my $item1 = 'item1';
my $item2 = 'item2';
my $item3 = 'item3';
my $item4 = 'item4';
my $item5 = 'item5';
push #{$allHash{$key1}}, $item1;
push #{$allHash{$key1}}, $item2;
$allHash{$key1}[2] = $item3;
$allHash{$key1}[3] = [$item4,$item5];
say Dumper(\%allHash);
Output
$VAR1 = {
'key1' => [
'item1',
'item2',
'item3',
[
'item4',
'item5'
]
]
};

Add an array to a hash entry that is already storing an array

I need to evaluate a series of strings that I want to convert into a hash of arrays. Take into account that, in this case, I want to add an array to an entry in a hash that it is already storing an array. I need to get the following hash:
ConfigurationHash{'Editor'} = (John, Mary, Jane, Peter)
I have stripped down my code to this example:
use strict;
use warnings;
my %ConfigurationHash;
my $String1 = "Editor=John,Mary";
my $String2 = "Editor=Jane,Peter";
my #Line1 = split ("=", $String1);
my #Line2 = split ("=", $String2);
my $Variable1 = #Line1[0];
my $Value1 = #Line1[1];
my $Variable2 = #Line2[0];
my $Value2 = #Line2[1];
my #Values1Array = split(",", $Value1);
my #Values2Array = split(",", $Value2);
if ( ! exists $ConfigurationHash{$Variable1} ) {
$ConfigurationHash{$Variable1} = #Values1Array;
}
else {
push (#ConfigurationHash{$Variable1}, #Values1Array);
}
which produces the following error:
Experimental push on scalar is now forbidden at ./test.pl line 25, near "#Values1Array)"
Execution of ./test.pl aborted due to compilation errors.
I know that the problem lies in references/dereferences, but my knowledge of perl is so basic that I'm not able to figure how to get there by myself.
Could anybody show me how to do it? I would also appreciate if you could show me how to iterate the values of the array in the hash once it is created.
It's unclear why you have $String2 and its derivatives in your code as they are never used. This code processes both strings
You simply need to push the list of values to the array corresponding to $Variable1 (dreadful choice of identifier) in the hash. Accomplish this by dereferencing the array element
use strict;
use warnings;
my %config;
my $s1 = 'Editor=John,Mary';
my $s2 = 'Editor=Jane,Peter';
for ( $s1, $s2 ) {
my ($key, #values) = split /[=,]/;
push #{ $config{$key} }, #values;
}
use Data::Dumper;
print Dumper \%config;
output
$VAR1 = {
'Editor' => [
'John',
'Mary',
'Jane',
'Peter'
]
};
This line isn't doing what you think it does.
$ConfigurationHash{$Variable1} = #Values1Array;
If you printed out what $ConfigurationHash{$Variable1} contains you'll find it only contains the size of #Values1Array.
You should be fine to use push but with a slight modification to what you've written.
push #{$ConfigurationHash{$Variable1}}, #Values1Array;
I've also removed the brackets as you don't need them.
As for iterating over the array, it is no different to iterating over a regular array. You were likely having problems iterating over it before as you didn't have an array
foreach my $whatever (#{$ConfigurationHash{$Variable1}})
{
# Code
}
Thank you to all who posted answers. #Borodin, you're right, I missed a second block that used $String2 and its derivatives, but I think it was obvious it was at the end and was similar to the if-else block in my original code.
Thank you, #chris-turner, for giving me the hint on how to use push the right way and pointing out the error in the $ConfigurationHash{$Variable1} = #Values1Array;
With all these contributions I figured out that the right code I was expecting is:
use strict;
use warnings;
my %ConfigurationHash;
my $String1 = "Editor=John,Mary";
my $String2 = "Editor=Jane,Peter";
my #Line1 = split ("=", $String1);
my #Line2 = split ("=", $String2);
my $Variable1 = $Line1[0];
my $Value1 = $Line1[1];
my $Variable2 = $Line2[0];
my $Value2 = $Line2[1];
my #Values1Array = split(",", $Value1);
my #Values2Array = split(",", $Value2);
if ( ! exists $ConfigurationHash{$Variable1} ) {
$ConfigurationHash{$Variable1} = \#Values1Array;
}
else {
#push (#ConfigurationHash{$Variable1}, #Values1Array);
push #{$ConfigurationHash{$Variable1}}, #Values1Array;
}
if ( ! exists $ConfigurationHash{$Variable2} ) {
$ConfigurationHash{$Variable2} = \#Values2Array;
}
else {
#push (#ConfigurationHash{$Variable2}, #Values2Array);
push #{$ConfigurationHash{$Variable2}}, #Values2Array;
}
use Data::Dumper;
print Dumper \%ConfigurationHash;
Which outputs the following:
$VAR1 = {
'Editor' => [
'John',
'Mary',
'Jane',
'Peter'
]
};

putting a hash value into an array in ruby

I am trying to insert a list of account numbers into an array from an json return, I turned the json return into an hash, but I cannot for some reason insert the values into an array. I checked the hash locations on irb, and it gets the account number, for an example the location my_hash["aws_accounts"][0]["owner_id"] will get me the first account number and my_hash["aws_accounts"][0]["status"]["level"] will get me the status of the first account.
I essentially want to iterate through all the accounts and store the account number if its respective status color is "yellow".
HERE IS MY CODE:
require 'json'
require 'rest-client'
j = RestClient.get 'https://chapi.cloudhealthtech.com/v1/aws_accounts?api_key=###&page=1&per_page=100'
my_hash = JSON.parse(j)
accnt_size = my_hash["aws_accounts"].size
intaccntsize = accnt_size.to_i
account_number_array = Array.new
x = 0
for accnt_iteration in x..intaccntsize do
puts accnt_iteration
if my_hash["aws_accounts"][accnt_iteration]["status"]["level"] == "yellow"
account_number_array.push(my_hash["aws_accounts"][accnt_iteration]["owner_id"])
end
end
HERE IS THE ERROR MESSAGE
in `block in <main>': undefined method `[]' for nil:NilClass (NoMethodError)
from C:/Users/----/Desktop/-----/ruby_aws_sdk.rb:12:in `each'
from C:/Users/------/Desktop/-------/ruby_aws_sdk.rb:12:in `<main>'
any suggestions will help. thanks.
The actual solution to your problem is to use the 3 dot range instead of 2 dot (3 dots is end-exclusive and 2 dots is end-inclusive) as seen in the following (this uses the same my_hash as my second code block below):
for x in 0..my_hash["aws_accounts"].size do
puts x
end
# 0
# 1
# 2
=> 0..2
my_hash["aws_accounts"][2]
=> nil
for x in 0...my_hash["aws_accounts"].size do
puts x
end
# 0
# 1
=> 0...2
my_hash["aws_accounts"][1]
=> {"owner_id"=>2, "status"=>{"level"=>"orange"}}
Instead of getting the number of accounts and trying to access them through their index, I would just iterate over the accounts on their own. Here's a quick sample, with what I believe (based on your description) are the relevant pieces of my_hash and your expected output.
my_hash = {
"aws_accounts" => [
{ "owner_id" => 1, "status" => { "level" => "yellow" } },
{ "owner_id" => 2, "status" => { "level" => "orange" } }
]
}
account_number_array = []
my_hash["aws_accounts"].each do |account|
if account["status"]["level"] == "yellow"
account_number_array << account["owner_id"]
end
end
puts account_number_array.inspect
# => [1]

smarty get offset of array

I have some trouble in prestashop 1.6 using smarty.
I have an array, but its offset are not reset for each product.
so for the firdst product, with attrivute it has offset 1,2,3,4 Then for the next product it has offest 5,6,7,8 etc.
I have that kind of array
$combinations Smarty_Variable Object (3)
->value = Array (4)
5 => Array (14)
attributes_values => Array (1)
1 => "S"
attributes => Array (1)
0 => 1
price => 0
specific_price => Array (0)
ecotax => 0
weight => 0
quantity => 20
reference => ""
unit_impact => 0
minimal_quantity => "1"
date_formatted => ""
available_date => ""
id_image => -1
list => "'1'"
6 => Array (14)
I try to go trhough this array but it does not work when I put empty offset (it is inside a foreach)
{$combinations[]['quantity']}
How can I tell him to go trhough the first iteration, and then in the second automatically ?
This return to me the following errors.
Fatal error: Cannot use [] for reading in /htdocs/tools/smarty/sysplugins/smarty_internal_templatebase.php(157) : eval()'d code on line 584
I can not tell him which offset to use, because for each product it goes up and is not reset to 0.
I would be very gratefull for anykind of help.
Here's how to do it, current return the first value of an array
{$combination = current($combinations)}
{$combination['quantity']}
in addition to #UnLoCo answer, if you need these keys 1,2 ... 7,8
{foreach from=$array key=key item=value}
{$key} => {$value}
{/foreach}
or
{foreach $array $key=>$value} {* like PHP style *}
{$key} => {$value}
{/foreach}
Also Smarty docs may help you http://www.smarty.net/docs/en/language.function.foreach.tpl

How to get the last element of an array and show the rest?

How do I get the last element of an array and show the rest of the elements?
Like this :
#myArray = (1,1,1,1,1,2);
Expected output :
SomeVariable1 = 11111
SomeVariable2 = 2
# print last element
print $myArray[-1];
# joined rest of the elements
print join "", #myArray[0 .. $#myArray-1] if #myArray >1;
If you don't mind modifying the array,
# print last element
print pop #myArray;
# joined rest of the elements
print join "", #myArray;
Сухой27 has given you the answer. I wanted to add that if you are creating a structured output, it might be nice to use a hash:
my #myArray = (1,1,1,1,1,2);
my %variables = (
SomeVariable1 => [ #myArray[0 .. $#myArray -1] ],
SomeVariable2 => [ $myArray[-1] ]
);
for my $key (keys %variables) {
print "$key => ",#{ $variables{$key} },"\n";
}
Output:
SomeVariable1 => 11111
SomeVariable2 => 2

Resources