Reduce an array to just the 'named' keys - php

I would like a hint or much better a solution for this:
I do a regular expresion match to an url for example '/product/100/'
preg_match('/^\/(?<name>\w+)\/(?<digit>\d+)\/$/', '/product/100/', $matches);
As result of this I get the following array on $matches:
array
0 => string '/product/100/' (length=13)
'name' => string 'product' (length=7)
1 => string 'product' (length=7)
'digit' => string '100' (length=3)
2 => string '100' (length=3)
How can I use reduce this array to get this?
array
'name' => string 'product' (length=7)
'digit' => string '100' (length=3)
After I get the matching expresions, I call a function and give the 'named' keys as arguments to the function.
call_user_func_array($view, $just_named_args_no_integer_keys);
I hope anyone can give me any hint.
Best Regards

Just run the keys you get from array_keys() through array_filter():
/* This is for PHP 5.3, I'm sure you'll figure out how to the same thing pre 5.3 :) */
$allKeys = array_keys($view);
$namedKeys = array_filter($allKeys, function($value) { return !is_numeric($value); });
Update
Did not read the question properly. In this case, actually just foreach over the data:
$namedValues = array();
foreach ($view as $key => $value)
if (!is_numeric($key))
$namedValues[$key] = $value;

Related

Extract just the strings from an array_column array return

I've got told many times, if there is a new question even on the same code to just create a new thread so here I am. Thanks to the guys for helping me with the previous question.
I have the following code:
/* Return an array of _octopus_ids */
$offices = array_map(
function($post) {
return array(
'id' => get_post_meta($post->ID, '_octopus_id', true),
);
},
$query->posts
);
/* Dump out all the multi-dimensional arrays */
var_dump($offices);
$test = array_column($offices, 'id');
var_dump($test);
var_dump($offices) dumps the following:
array (size=10)
0 =>
array (size=1)
'id' => string '1382' (length=4)
1 =>
array (size=1)
'id' => string '1330' (length=4)
var_dump($test) dumps the following:
array (size=10)
0 => string '1382' (length=4)
1 => string '1330' (length=4)
Problem:
How can I use the following code:
$results = $octopus->get_all('employees/' . $test; which results in an Notice: Array to string conversion error.
I want to be able to make a results call such as this $results = $octopus->get_all('employees/1382'); - So I want just the numeric string of $test to be appended to the end of employees/
If I hardcode the 1382 after employees/, I get the following result:
object(stdClass)[1325]
public 'id' => int 1382
What's the proper way to array of strings into just strings?

PHP: Remove empty values from array and shift values up

I'm trying to create a function that shifts array values up a key if the previous key is empty and one after is set. E.g. this array:
array (size=4)
'row1' => string 'row1' (length=4)
'row2' => string '' (length=0)
'row3' => string '' (length=0)
'row4' => string 'row4' (length=4)
should become this after my function call:
array (size=4)
'row1' => string 'row1' (length=4)
'row2' => string 'row4' (length=4)
'row3' => string '' (length=0)
'row4' => string '' (length=0)
I do have a working function, however, it uses a lot of if statements and I'm 100% sure that it could be done more efficiently, any ideas on how to achieve efficiently?
Thanks
You can do this in a single line, making use of array_ functions.
$o = array_combine(array_keys($input), array_pad(array_filter($input), count($input), ''));
array_filter will, by default, remove any empty values from the array
array_pad will pad the array to the length of the original array, adding an empty string
array_keys will get the keys of the original array
array_combine will combine the keys with the values
The above would output the following:
array (size=4)
'row1' => string 'row1' (length=4)
'row2' => string 'row4' (length=4)
'row3' => string '' (length=0)
'row4' => string '' (length=0)
Here's a demo
Lets try this with a big array, and hope this will help you out. The way of question is different but your question is same as
1. Getting empty values at end.
2. Non empty at starting without changing order
3. Without changing keys order
If you think about any array this result come to end.
Try this code snippet here
<?php
$array=$tempArray=array(
'row1' => 'row1',
'row2' => '' ,
'row3' => '',
'row6' => 'row6' ,
'row4' => 'row4' ,
'row5' => '',
'row7' => 'row7' ,
'row8' => ''
);
$result=array();
$tempArray= array_values($tempArray);
$tempArray=array_values(array_filter($tempArray));
foreach(array_keys($array) as $key_key => $key)
{
if(!empty($tempArray[$key_key]))
{
$result[$key]=$tempArray[$key_key];
}
else
{
$result[$key]="";
}
}
print_r($result);
Output:
Array
(
[row1] => row1
[row2] => row6
[row3] => row4
[row6] => row7
[row4] =>
[row5] =>
[row7] =>
[row8] =>
)
unfortunately you did not share your code, so we cannot know what you do exactly
also it would be helpful if you added the array as code we can run directly and do not need to edit/re-create
I would
ignore the keys for processing the list when possible
unset entries that are nor needed any longer
iterate lists with foreach
apart from this you can sort lists in PHP (by value, key; asc, desc; with/without association), they have a nice overview on that in the manual.
example steps:
<?php
$a['row1'] = 'row1';
$a['row2'] = '';
$a['row3'] = '';
$a['row4'] = 'row4';
print_r( $a );
arsort($a);
print_r( $a );
//get rid of double entries
$f=array_flip( $a );
//get rid of empty entries
unset($f['']);
print_r( array_flip( $f ) );
?>
EDIT
$yourarr=array('row1'=>"row1",'row2'=>"",'row3'=>"",'row4'=>"row4");
$array1=array();
$array2=array();
foreach ($yourarr as $key =>$val){
if(empty($val)){
$array2[$key]=$val;
}else{
$array1[$key]=$val;
}
}
$newarr=array_merge($array1,$array2);
//<!-- Try This if you want to remove the empty indexes just put ! infront of the empty and delete the else part and to reset the row count -->
$i=1;
$newarr2=array();
foreach($newarr as $key =>$val){
$newarr2['row'.$i]=$val;
$i++;
}
var_dump($newarr2);
OUTUT
D:\wamp64\www\test\index.php:21:
array (size=4)
'row1' => string 'row1' (length=4)
'row2' => string 'row4' (length=4)
'row3' => string '' (length=0)
'row4' => string '' (length=0)

Php Array sorting assoc key after intersect key

Currently I have this:
$pattern = array('industry_id','category_id','subcategory_id');
$data = array('advert_id' => string '261501' (length=6)
'advert_type_id' => string '7' (length=1)
'user_id' => string '6221' (length=4)
'industry_id' => string '17' (length=2)
'category_id' => string '769' (length=3)
'subcategory_id' => string '868' (length=3)
'model' => string 'Custom Semi Drop Deck Trailer' (length=29)
'description' => string 'Industry: Trailer );
Then:
array_intersect_key( $data , array_flip($pattern) );
Using array_interect_key & array_flip to get the values from $data based on $pattern, I will get a result like this:
array (size=3)
'category_id' => string '769' (length=3)
'subcategory_id' => string '930' (length=3)
'industry_id' => string '17' (length=2)
Unfortunately as you can see the result key sorting is not the same that I declared in $pattern. Is there a shorthand way to sort it like I declared in $pattern because after this I want to implode the array and do something like this industry_id.category_id.subcategory_id without hard coding the keys.
Since you already figured out array_intersect_key method which will not get you the desired key ordering of $pattern, try this instead:
// since original $pattern is not ASSOC (only vals)
// flip it so defined vals become keys
$pattern_flipped = array_flip($pattern);
$result = array();
foreach ($pattern_flipped as $k => $v) {
if (isset($data[$k])) {
$result[$k] = $data[$k];
}
}
var_dump($result); // test
// can use original 0 1 2 dynamic keys for concatenation
echo $result[$pattern[0]], $result[$pattern[1]], $result[$pattern[2]], '<br>';
// or use hardcoded keys
echo $result['industry_id'], $result['category_id'], $result['subcategory_id'], '<br>';
You know I'm not sure how you're getting the result you describe. I've tried your code and I get
array (size=3)
'industry_id' => string '17' (length=2)
'category_id' => string '769' (length=3)
'subcategory_id' => string '868' (length=3)
You could do this another way though using array_filter
$newData = array_filter($data, function($key) use ($pattern) {
if (in_array($key, $pattern))
return true;
}, ARRAY_FILTER_USE_KEY)

using reference (&) in foreach add `&` in output array? is it a bug

I am using PHP 5.3.5, and I am stuck with an error. I have an array
$input = array(
0=>array(
'a'=>'one0',
'b'=>'two0',
'c'=>'three0',
'd'=>'four0',
'e'=>'five0'
),
1=>array(
'a'=>'one1',
'b'=>'two1',
'c'=>'three1',
'd'=>'four1',
'e'=>'five1'
)
);
I use array_splice to remove the initial two values from each array
by using &(value by reference) in foreach
foreach ($input as $bk => &$bv) {
$op[]=array_splice($bv,0,2);
}
Now when I see the $input then it adds a & just before the second array.
var_dump($input); shows this
array
0 =>
array
'c' => string 'three0' (length=6)
'd' => string 'four0' (length=5)
'e' => string 'five0' (length=5)
1 => & <====================================From where this `&` comes?
array
'c' => string 'three1' (length=6)
'd' => string 'four1' (length=5)
'e' => string 'five1' (length=5)
Where does & come from and how does it produce such array? Is it valid?
If I remove & in the foreach, it does not gives me desired array. Am I doing something wrong?
It's pretty counter-intuitive but it isn't actually a bug. When you use references in a loop, you're advised to unset the reference right after the loop:
foreach ($input as $bk => &$bv) {
$op[]=array_splice($bv,0,2);
}
unset($bv);

what's wrong with this php code?

Ok, the idea here is to have code that will append SF_ to all key names in an array.
I took my array (which is part of an object), flipped it, added the SF_, and flipped it back.
Somewhere in the process I lost some fields...
here's what I started with:
object(stdClass)[12]
public 'Affiliate_Code__c' => string 'XX-TXUJC3' (length=9)
public 'AltEmail__c' => string 'benny#oxpublishing.com' (length=22)
public 'City' => string 'Mobile' (length=6)
public 'Email' => string 'benny#oxpublishing.com' (length=22)
public 'Fax__c' => string '251-300-1234' (length=12)
public 'FirstName' => string 'Benny' (length=5)
public 'LastName' => string 'Butler' (length=6)
public 'Phone' => string '251-300-3530' (length=12)
public 'PostalCode' => string '36606' (length=5)
public 'State' => string 'AL' (length=2)
public 'Street' => string '851 E I-65 Service Rd' (length=21)
public 'test1__c' => float 1
array
'SF_Affiliate_Code__c' => string 'XX-TXUJC3' (length=9)
'SF_Email' => string 'benny#oxpublishing.com' (length=22)
'SF_City' => string 'Mobile' (length=6)
'SF_Fax__c' => string '251-300-1234' (length=12)
'SF_FirstName' => string 'Benny' (length=5)
'SF_LastName' => string 'Butler' (length=6)
'SF_Phone' => string '251-300-3530' (length=12)
'SF_PostalCode' => int 36606
'SF_State' => string 'AL' (length=2)
'SF_Street' => string '851 E I-65 Service Rd' (length=21)
And here's my code:
$response = $mySforceConnection->query(($query));
foreach ($response->records as $SF) {
}
var_dump($SF);
$SF = array_flip($SF);
foreach ($SF as $key => $value){
$SF[$key] = 'SF_'.$value;
}
$SF = array_flip($SF);
echo "<pre>";
var_dump($SF);
echo "</pre>";
extract($SF);
Any idea?
I'm new to OO programming of any sort, and I'm sure this has something to do with it.
I'm so stupid I have to do:
foreach ($response->records as $SF) { }
because I don't know how to get to that array any other way.
Help!
Thanks!
When you do the flip, you end up with duplicate keys - the values become the keys, and your values are not unique (e.g. Email and AltEmail__c both have the same value).
Rather than doing a flip then flipping back, just create a new array and copy the values in with the new keys:
$SF_new = array();
foreach($SF as $key => $value ) {
$SF_new['SF_' . $key] = $value;
}
// And if you want to continue using the $SF name...
$SF = $SF_new;
array_flip will flip the values and keys, as you said. A PHP array cannot have multiple keys with the same name. Try something like this to avoid flipping:
<?php
$SF = array();
foreach($response->records as $key => $value)
{
$SF['SF_' . $key] = $value;
}
About the way you get to the array in the object, this is the proper way to do it.
$SF = get_object_vars($response);
Will transform your object into an array.
flip swaps keys and values. because you have values that share the same value, you lose them in the flip.

Categories