How can I set multifilter or multicallback?
I want filter data by City and Confirm together.
Input data:
$data1 = array(
"L1" => array('Vanessa', 'Prague', 'OK'),
"L2" => array('Alex', 'Paris', 'OK'),
"L3" => array('Paul', 'Paris', 'OK'),
"L4" => array('John', 'Madrid', 'OK'),
"L5" => array('Jane', 'London', 'Waiting'),
"L6" => array('David', 'Prague', 'OK'),
"L7" => array('Martin', 'Prague', 'Waiting'),
"L8" => array('Frank', 'Prague', 'OK'),
"L9" => array('Joseph', 'Prague', 'Waiting'),
);
Filter code:
$ByConfirm = 'OK';
$ByCity = 'Prague';
Below is my problem. I try use &&, but it works separately, I need cooperation of $filterByConfirm + $filterByCity
$new = array_filter($data1, $filterByConfirm && $filterByCity);
$filterByConfirm = $new = array_filter($data1, function ($var) use ($ByConfirm) {
return ($var[2] == $ByConfirm);
});
$filterByCity = $new = array_filter($data1, function ($var) use ($ByCity) {
return ($var[1] == $ByCity);
});
Actual result:
Name City Confirm
Vanessa Prague OK
David Prague OK
Martin Prague Waiting
Frank Prague OK
Joseph Prague Waiting
I need:
Name City Confirm
Vanessa Prague OK
David Prague OK
Frank Prague OK
Finally, here is solution:
PHP 5.2: Filter array with multiple arguments performance
$arrayToCompare = array('type'=>'fruits','has_name'=>'OK', 'has_color'=>'Prague');
$new = array_filter(
$data1,
function ($arr) use ($arrayToCompare) { // PHP 5.3 is required here!!
return ($arr[2] == $arrayToCompare['has_name']
AND $arr[1] == $arrayToCompare['has_color']);
}
);
Related
I'm trying to write a Perl script that will update our eBay listings descriptions without having to keep logging in (running across multiple marketplaces if proving tricky to keep stock levels, descriptions etc updated). Here is what I have so far:
my $ebay = new Net::eBay( {
SiteLevel => 'prod',
DeveloperKey => 'x',
ApplicationKey => 'x',
CertificateKey => 'x',
Token => 'x',
} );
$ebay->setDefaults( { API => 2, compatibility => 900 } );
my $new_desc = q|<meta name="viewport" content="width=device-width, initial-scale=1.0">
<p>We are proud to announce our first ever badge! With an easy-to-iron
on backing, fitting couldn't be any easier! We have designed the path to
be a perfect addition to any piece of cosplay costume. Please do send
in the photos of it being used on your costumes, as we would love to
share.</p>
<p>The badge is 7 x 7 cm / 2 x 2 inches in size, and 2mm thi<br></p>|;
my $result = $ebay->submitRequest( "ReviseItem",
{
DetailLevel => "ReturnAll",
ErrorLevel => "1",
SiteId => "1",
Item => {
Description => \$new_desc,
ItemID => 253430606975
},
ItemID => 253430606975
}) || die;
print "Result: " . Dumper( $result ) . "\n";
I get an error when running it though:
'Errors' => [
{
'ShortMessage' => 'Return Policy Attribute Not Valid',
'ErrorClassification' => 'RequestError',
'ErrorCode' => '21920200',
'LongMessage' => 'Return Policy Attribute returnDescription Not Valid On This Site',
'SeverityCode' => 'Warning',
'ErrorParameters' => {
'Value' => 'returnDescription',
'ParamID' => '0'
}
},
{
'ShortMessage' => 'Description is missing.',
'ErrorClassification' => 'RequestError',
'ErrorCode' => '106',
'SeverityCode' => 'Error',
'LongMessage' => 'A description is required.'
}
],
Am I misunderstanding what gets passed in? from what I can understand, you just pass in the params you want to change?
UPDATE: As suggested by Dave, I'm giving Marketplace::Ebay a go. Just testing by trying to select one of my items:
my $ebay = Marketplace::Ebay->new(
production => 1,
site_id => 3,
developer_key => 'xx',
application_key => 'xx',
certificate_key => 'xxx',
token => 'xx',
xsd_file => 'ebaySvc.xsd',
);
my $res = $ebay->api_call('GetItem', { ItemID => 253430606975 });
print Dumper($res);
But I get some weird error:
error: element `{urn:ebay:apis:eBLBaseComponents}GiftIcon' not
processed for {urn:ebay:apis:eBLBaseComponents}GetItemResponse/Item at
//[5]/*[6] $VAR1 = undef;
Any ideas?
Ah ha - got it! The issue seemed to be around the way the HTML was being passed along. If I put it inside a CDATA tag, it works fine:
my $new_desc = q|<![CDATA[
some html etc here
]]>|;
my $result = $ebay->submitRequest( "ReviseItem",
{
DetailLevel => "ReturnAll",
ErrorLevel => "1",
SiteId => "1",
Item => {
Description => $new_desc,
ItemID => 253430606975
},
ItemID => 253430606975
}) || die;
...and updates perfectly
I signed up for the Mapquest API service, and I am now testing my application, using PHP.
Under Manage Keys, I created a new key, and Mapquest gave me:
Consumer Key
Consumer Secret
I clicked on Approve All Keys
I looked up the documentation for Geocoding API Post Batch, and it says that I should include the key as one of the params.
I assumed it's the Consumer Key, so I included mine. However, when I make the call, I get the following response:
The AppKey submitted with this request is invalid.
My code:
$results = mapquest_v1_geocoding_batch_get_location(array('123 Main St, Anytown, WA', '123 Main St, Anytown, WA 98052'));
pretty_print($results);
function mapquest_v1_geocoding_batch_get_location($locations)
{
//&location=Denver, CO&location=1555 Blake St, Denver, CO 80202&location=Boulder&key=KEY
$postfields = array (
'inFormat' => 'kvp',
'outFormat' => 'json',
'thumbMaps' => FALSE,
'maxResults' => 1
);
$postfields_string = http_build_query($postfields);
foreach ($locations as $location) {
$postfields_string .= '&'.http_build_query(array('location' => $location));
}
$postfields_string .= '&'.http_build_query(array('key' => PARN_MAPQUEST_TW_TO_FB_KEY));
pretty_echo($postfields_string);
$url = 'https://www.mapquestapi.com/geocoding/v1/batch';
return jhm_curl_post_call($url, $postfields);
}
function jhm_curl_post_call($url, $postfields, $setopts_array = FALSE)
{
$results = array();
if (!$setopts_array) {
$setopts_array = array();
}
if (!isset($setopts_array[CURLOPT_RETURNTRANSFER])) {
$setopts_array[CURLOPT_RETURNTRANSFER] = TRUE;
}
if (!isset($setopts_array[CURLOPT_POST])) {
$setopts_array[CURLOPT_POST] = TRUE;
}
$setopts_array[CURLOPT_URL] = $url;
$setopts_array[CURLOPT_POSTFIELDS] = http_build_query($postfields);
$ch = curl_init();
curl_setopt_array ($ch , $setopts_array);
$results['json_response'] = curl_exec($ch);
$results['response'] = json_decode($results['json_response'], TRUE);
$results['info'] = curl_getinfo($ch);
$results['curl_errno'] = curl_errno($ch);
$results['curl_error'] = curl_error($ch);
curl_close($ch);
return $results;
}
This is the $postfields_string:
inFormat=kvp&outFormat=json&thumbMaps=0&maxResults=1&location=123+Main+St%2C+Anytown%2C+WA&location=123+Main+St%2C+Anytown%2C+WA+98052&key=xxxxxxxxxxxxxxxxxxxxxxxxxxxx
and the results of the call:
Array
(
[json_response] => The AppKey submitted with this request is invalid.
[info] => Array
(
[url] => https://www.mapquestapi.com/geocoding/v1/batch
[content_type] => text/plain
[http_code] => 403
[header_size] => 236
[request_size] => 198
[filetime] => -1
[ssl_verify_result] => 0
[redirect_count] => 0
[total_time] => 0.265
[namelookup_time] => 0.062
[connect_time] => 0.109
[pretransfer_time] => 0.203
[size_upload] => 52
[size_download] => 50
[speed_download] => 188
[speed_upload] => 196
[download_content_length] => 50
[upload_content_length] => 52
[starttransfer_time] => 0.265
[redirect_time] => 0
[redirect_url] =>
[primary_ip] => 207.200.103.5
[certinfo] => Array
(
)
[primary_port] => 443
[local_ip] => 192.168.1.4
[local_port] => 50514
)
[curl_errno] => 0
[curl_error] =>
)
The key needs to be in the url parameters after mapquestapi.com rather than in the post data. Then you should be good to go.
I am always confusing or don't know how to handle hash in perl.
So here is the problem,
Considering the whole thing, i am trying to change the key name in the below hash.
my %hash_new = {
'customername' => 'Lee & toys',
'employee_name' => 'Checngwang',
'customer_id' => 'X82349K',
'customer_address' => 'classic denver ranch, meadows drive',
'types' => 'category la',
};
my %selectCols = ('customername' => 'CUSTOMERNAME','employee_name' => 'EMP_NAME','customer_id' => 'cusid','customer_address' => 'cusaddr','types' => 'Typs');
my %new_hash = ();
foreach my $hash_keys (keys %hash_new){
my $newKey = $selectCols{$hash_keys};
$new_hash{$newKey} = $hash_new{$hash_keys};
}
print Dumper %new_hash;
Output of %new_hash is something like a key value combination of continuous string as below,
CUTOMERNAMELee & toysEMP_NAMEChecngwangcus_idX82349Kcusaddrclassic denver ranch, meadows driveTypscategory la
But instead of this, i need the hash like,
$VAR1 = {
'CUSTOMERNAME' => 'Lee & toys',
'EMP_NAME' => 'Checngwang',
'cusid' => 'X82349K',
'cusaddr' => 'classic denver ranch, meadows drive',
'Typs' => 'category la',
};
Please help me around this!
If I understood you correctly, then this works:
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
my %hash_new = (
'customername' => 'Lee & toys',
'employee_name' => 'Checngwang',
'customer_id' => 'X82349K',
'customer_address' => 'classic denver ranch, meadows drive',
'types' => 'category la'
);
my %selectCols = (
'customername' => 'CUSTOMERNAME',
'employee_name' => 'EMP_NAME',
'customer_id' => 'cusid',
'customer_address' => 'cusaddr',
'types' => 'Typs'
);
my %new_hash = ();
foreach my $hash_keys (keys %hash_new){
my $newKey = $selectCols{$hash_keys};
$new_hash{$newKey} = $hash_new{$hash_keys};
}
print Dumper \%new_hash;
The only code I changed in your code was using () instead of {} in %hash_new and escaped the % in the Dumper statement. The % should be escaped because Dumper expects a reference, not a hash (that's true also for all other Perl variable types in use with Dumper).
Output:
$VAR1 = {
'Typs' => 'category la',
'cusaddr' => 'classic denver ranch, meadows drive',
'EMP_NAME' => 'Checngwang',
'cusid' => 'X82349K',
'CUSTOMERNAME' => 'Lee & toys'
};
Also, don't use confusing names like %hash_new and %new_hash. It's - well - confusing.
I am trying to process a perl data structure that I have outputted using Data::Dumper
$VAR1 = 'GAHD';
$VAR2 = [
{ 'COUNTRY' => 'US',
'NAME' => 'K. Long',
'DATE_OF_BIRTH' => '7/27/1957',
'POSITION' => 'SENIOR OFFICER',
'AGE' => 57,
'GRADE' => 'P5'
},
{ 'COUNTRY' => 'US',
'NAME' => 'J. Buber',
'DATE_OF_BIRTH' => '12/11/1957',
'POSITION' => 'CHIEF',
'GRADE' => 'D1'
},
{ 'COUNTRY' => 'US',
'NAME' => 'M. Amsi',
'DATE_OF_BIRTH' => '1/1/1957',
'POSITION' => 'SENIOR ANIMAL HEALTH OFFICER',
'AGE' => 57,
'GRADE' => 'P5'
},
{ 'COUNTRY' => 'US',
'NAME' => 'E. Xenu',
'DATE_OF_BIRTH' => '8/31/1964',
'POSITION' => 'SENIOR OFFICER',
'AGE' => 50,
'GRADE' => 'P5'
},
];
$VAR3 = 'GAGD';
$VAR4 = [
{ 'COUNTRY' => 'US',
'NAME' => 'P. Cheru',
'DATE_OF_BIRTH' => '6/18/1966',
'POSITION' => 'ANIMAL PRODUCTION OFFICER',
'AGE' => 48,
'GRADE' => 'P4'
},
{ 'COUNTRY' => 'US',
'NAME' => 'B. Burns',
'DATE_OF_BIRTH' => '2/4/1962',
'POSITION' => 'ANIMAL PRODUCTION OFFICER',
'AGE' => 52,
'GRADE' => 'P4'
},
{ 'COUNTRY' => 'US',
'NAME' => 'R. Mung',
'DATE_OF_BIRTH' => '12/13/1968',
'POSITION' => 'ANIMAL PRODUCTION OFFICER',
'AGE' => 45,
'GRADE' => 'P4'
},
{ 'COUNTRY' => 'GERMANY',
'NAME' => 'B. Scherf',
'DATE_OF_BIRTH' => '8/31/1964',
'POSITION' => 'ANIMAL PRODUCTION OFFICER',
'AGE' => 50,
'GRADE' => 'P4'
},
{ 'COUNTRY' => 'GERMANY',
'NAME' => 'I. Hoffmann',
'DATE_OF_BIRTH' => '2/21/1960',
'POSITION' => 'CHIEF',
'AGE' => 54,
'GRADE' => 'P5'
},
];
The following is outputted:
1 ADG JUNIOR OFFICER K. King
1 DG SENIOR DIRECTOR K. King
3 P5 SENIOR OFFICER R. Forest
R.Forest
K. King
1 P3 JUNIOR OFFICER K. King
3 P1 FORESTRY OFFICER P. Smith
T. Turner
K. Turner
1 P1 GENERAL OFFICER K. King
I would like to count the number of GRADES and POSITIONS by Division. Here is the code that I have put together thus far:
#Push data read from a flat file and while loop
push #{ $grades{ $_->{GRADE} }{ $_->{POSITION} } }, $_->{NAME} for #$AG;
for my $key (
sort { substr( $a, 0, 1 ) cmp substr( $b, 0, 1 ) || substr( $b, 0, 2 ) cmp substr( $a, 0, 2 ) }
keys %grades
)
{
for my $pos ( sort { $a cmp $b } keys %{ $grades{$key} } ) {
my $names = $grades{$key}->{$pos};
my $count = scalar #$names;
print $count, ' ', $key, ' ', $pos, ' ', $names->[0], "\n";
print ' ', $names->[$_], "\n" for 1 .. $#$names;
}
}
The code will stop outputting results if duplicate POSITIONS and GRADES data (i.e. P1, Senior Officer) appear in another Division.
I do not know how to access the Hash of Hash by Division (i.e. GAGD, GAGHD,etc.) so that the same GRADEs and POSITIONs will be outputted per division.
Here is what I really need:
**GAGD**
1 ADG JUNIOR OFFICER K. King
1 DG SENIOR DIRECTOR K. King
3 P5 SENIOR OFFICER R. Forest
R.Forest
K. King
1 P3 JUNIOR OFFICER K. King
3 P1 FORESTRY OFFICER P. Smith
T. Turner
K. Turner
1 P1 GENERAL OFFICER K. King
**GAGHD**
1 P3 JUNIOR OFFICER P. Green
3 P1 FORESTRY OFFICER R. Brown
F. Boo
K. Church
1 P1 GENERAL OFFICER D. Peefer
etc.
etc.
It seems you want to hash the information by Division, then count and store names by grade + position. The following seems to work for me:
#!/usr/bin/perl
use warnings;
use strict;
use feature qw{ say };
my %grades = (
GAHD => [ {
NAME => 'K. Long',
POSITION => 'SENIOR OFFICER',
GRADE => 'P5'
},
{
NAME => 'J. Buber',
POSITION => 'CHIEF',
GRADE => 'D1'
},
{
NAME => 'M. Amsi',
POSITION => 'SENIOR ANIMAL HEALTH OFFICER',
GRADE => 'P5'
},
{
NAME => 'E. Xenu',
POSITION => 'SENIOR OFFICER',
GRADE => 'P5'
},
],
GAGD => [
{
NAME => 'P. Cheru',
POSITION => 'ANIMAL PRODUCTION OFFICER',
GRADE => 'P4'
},
{
NAME => 'B. Burns',
POSITION => 'ANIMAL PRODUCTION OFFICER',
GRADE => 'P4'
},
{
NAME => 'R. Mung',
POSITION => 'ANIMAL PRODUCTION OFFICER',
GRADE => 'P4'
},
{
NAME => 'B. Scherf',
POSITION => 'ANIMAL PRODUCTION OFFICER',
GRADE => 'P4'
},
{
NAME => 'I. Hoffmann',
POSITION => 'CHIEF',
GRADE => 'P5'
},
]);
for my $division (keys %grades) {
say "**$division**";
my %group;
for my $person (#{ $grades{$division} }) {
my $position = join ' ', #{ $person }{qw{GRADE POSITION}};
push #{ $group{$position} }, $person->{NAME};
}
for my $position (keys %group) {
say join ' ', scalar #{ $group{$position} },
$position,
$group{$position}[0];
my #remaining_names = #{ $group{$position} };
shift #remaining_names;
say "\t$_" for #remaining_names;
}
say q();
}
Update
If you store more information than a name for a person in an array ref (push push #{ $group{$position} }, [ ... ];), you can then retrieve it by dereferencing each reference, for example in map:
say join ' ', scalar #{ $group{$position} },
$position,
join "\n\t", map "#$_", #{ $group{$position} };
You're almost there with the code that you've got. Assuming that the hash you've printed out is called %grades, I would do the following:
foreach my $g (sort keys %$grades) {
print "**$g**\n";
# put the info to be printed in a temporary hash
my %temp;
foreach (#{$grades->{$g}}) {
push #{$temp{ $_->{GRADE}." ".$_->{POSITION} }}, $_->{NAME};
}
foreach (sort keys %temp) {
# print a count of the number of names, then the grade/position info
print scalar #{$temp{$_}} . " $_ "
# #{$temp{$_}} holds the names, so just sort them and print them out.
. join("\n\t\t\t", sort #{$temp{$_}}) . "\n";
}
}
SELECT me.id, me.date_created, me.date_updated, me.yes,
me.name, me.description, me.currency, me.locked, me.skip,
me.uri_part, me.user_id,
yes + currency as weight
FROM ideas me having ((weight < 5)) order by weight;
How can I generate that query in DBIx::Class without using literal SQL like this:
my $query = $rs->search({},
{
'+select' => \[
'yes + currency as weight',
],
rows => 1,
order_by => { -desc => [qw/weight name/] },
having => {
weight => { '<' => $self->yes + $self->currency },
},
});
use Data::Dumper;
warn Dumper($query->as_query);
I tried using -as, however, it seems to only be useful for working with columns generated from functions, as this:
'+select' => {
'yes + currency', '-as' => 'weight'
}
generates an error
"Odd number of elements in anonymous hash at
/data/TGC/lib/TGC/DB/Result/Idea.pm line 105, line 1000.
DBIx::Class::SQLMaker::_recurse_fields(): Malformed select argument -
too many keys in hash: SCALAR(0xbf14c40),weight"
Probably the most idiomatic thing I can think of in SQL Abstract expression, without straining too hard:
#!/usr/bin/env perl
use Modern::Perl;
use MySchema;
use Data::Dumper;
my $schema = MySchema->connect('dbi:SQLite:example.db');
my $rs = $schema->resultset('Sample')->search(
{
weight => { '<' => 5 },
},
{
'+select' => [
{ '' => \'`me`.`yes` + `me`.`currency`', -as => 'weight' }
]
}
);
say Dumper( $rs->as_query() );
Which is a contrived wrapping of the column names, but it does the job, sort of. Just don't know of any way to abstract the + here. But stil:
'(SELECT me.name, me.yes, me.currency, ( me.yes + me.currency ) AS weight FROM sample me WHERE ( weight < ? ))',
Unless you are just going for idiomatic perl, in which case:
{ '' => \(join " + ", qw/`me`.`yes` `me`.`currency`/), -as => 'weight' }
But either way seems a little contrived considering both forms are longer than the literal string.
Also note that weight is referenced in WHERE and not HAVING which is because that will blow up on various SQL engines.
The '+as' should be at the same level as '+select'
$idea = $rs->search({-and => [
name => { '<' => $self->name },
]},
{
'+select' => [
'yes + currency'
],
'+as' => [qw/weight/],
rows => 1,
order_by => ['weight', 'name'],
having => {
weight => { '<' => $self->yes + $self->currency },
},
})->single;