Extracting values from arrays in custom fields - arrays

I'm trying to come up with a single array of all values in specific custom fields. The values themselves are also arrays. I've tried all sorts of array functions but haven't come across the right one or the right combination. Here is my code thus far:
$args = array(
'post_type' => 'match_report',
'post_status' => 'publish',
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'report_home-scorers'
),
array(
'key' => 'report_away-scorers'
)
)
);
$reportscore = new WP_Query($args);
$scorersResults = array();
if ( $reportscore->have_posts() ) {
while ( $reportscore->have_posts() ) {
$reportscore->the_post();
$homescorers = get_post_meta($post->ID,'report_home-scorers',false);
$awayscorers = get_post_meta($post->ID,'report_away-scorers',false);
foreach ($homescorers as $homescorer){
array_push($scorersResults, $homescorer);
}
foreach ($awayscorers as $awayscorer){
array_push($scorersResults, $awayscorer);
}
?>
<?php } wp_reset_postdata(); //endif
}//endwhile
$scorerResults = remove_empty($scorersResults);
function remove_empty($array) {
return array_filter($array, '_remove_empty_internal');
}
function _remove_empty_internal($value) {
return !empty($value) || $value === 0;
}
Here what I get if I print_r($scorerResults); :
Array
(
[1] => Array
(
[0] => 1
[1] => 63
)
[2] => Array
(
[0] => 263
[1] => 195
)
[3] => Array
(
[0] =>
)
[4] => Array
(
[0] =>
)
)
I just want the values in the internal arrays in an array.

Assuming you want the $scoreResults array to end up as array(1,63,263,195) you could use the array_reduce function like this:
function gatherScores($lhs, $rhs) {
foreach ($rhs as $key => $value)
if ($value)
$lhs[] = $value;
return $lhs;
}
$scorerResults = array_reduce($scorerResults, "gatherScores", array());
I'm not sure what the blank values are in your third and fourth arrays and how they should be handled, so you may need to change the if ($value) condition to check for something different. As it stands it'll obviously also filter out zero scores.

Related

How to remove first dimension of an array without loosing keys?

How can i remove the first dimansion of a multidemensional Array without loosing the keys?
i have an Array that have multiple arrays inside
the firstkey is a Date and the secondkey is the hour.
my Output is:
Array
(
[0] => Array
(
[firstkey] => Array
(
[secondkey] => Array
(
[0] => 7
[1] => 8
)
)
)
[1] => Array
(
[firstkey] => Array
(
[secondkey] => Array
(
[0] => 7
[1] => 8
)
)
)
)
and i want this:
Array
(
[firstkey] => Array
(
[secondkey] => Array
(
[0] => x
[1] => y
[2] => z
[3] => r
)
)
)
i also tried array_merge_recursive() but instead of putting the values to the secondkey it creates a new array with an incremental key
okay found a solution on:
PHP : multidimensional array merge recursive
function array_merge_recursive_ex(array $array1, array $array2)
{
$merged = $array1;
foreach ($array2 as $key => & $value) {
if (is_array($value) && isset($merged[$key]) && is_array($merged[$key])) {
$merged[$key] = array_merge_recursive_ex($merged[$key], $value);
} else if (is_numeric($key)) {
if (!in_array($value, $merged)) {
$merged[] = $value;
}
} else {
$merged[$key] = $value;
}
}
return $merged;
}
and with this function i can merge that mutlidemensional array without loosing keys:
$newarray =[];
foreach($array as $firstkey){
$newarray = array_merge_recursive_ex($newarray, $firstkey);
}

Array reduce find the small distance and return id

I use google matrix for calculate the best distance with the multiple address.
I want display the id of a small distance
My array return by the API
$com = Array(
[0] => Array (
[id] => 12
[km] => 833 km
)
[1] => Array (
[id] => 4
[km] => 546km
)
[1] => Array (
[id] => 45
[km] => 1200km
)
)
I want display the ID of small distance ( for this exemple the id is "4")
I have tried this :
$min = array_reduce($commercant,
function ($min, $item) {
if ($item['km'] < $min['km']) {
return $item;
}
return $min;
},
array('id' => -1, 'km' => PHP_INT_MAX));
echo $min['id'];
This code doesn't work and i don't know why !
if you have an idea....
Thx
use this code
usort($com, function($a, $b) {
return $a['km'] - $b['km'];
});
echo !empty($com[0]['id']) ? $com[0]['id'] : "";
it will sort your array in desc order of distance, from this sorted array you can pick first element of array.
Hope this will help you!
With ordinary sorting, you can achieve result.
http://php.net/manual/en/function.usort.php
$x = [
['id' => 12, 'km' => '833km'],
['id' => 4, 'km' => '546km'],
['id' => 45, 'km' => '1200km']
];
function cmp_by_kms($arr1, $arr2) {
$km1 = intval($arr1['km']);
$km2 = intval($arr2['km']);
if ($km1 == $km2) { return 0; }
return ($km1<$km2) ? -1 : 1;
}
usort($x, "cmp_by_kms");
print_r($x[0]);
#=> Array
(
[id] => 4
[km] => 546km
)

A hash::combine array

I have this array from a sql query :
[0] => Array
(
[T1] => Array
(
[First] => A
[Second] => Apples
[LastChild] => F
)
[0] => Array
(
[LastChildNb] => 23
)
)
I would like to have this result :
[0] => Array
(
[0] => Array
(
[First] => A
[Second] => Apples
[LastChild] => F
[LastChildNb] => 23
)
)
How do I do this ? I think I should use "hash::combine", but what would the code be ?
You could do something like this, with $arr being your array above:
$arr = array_reduce($arr, function(&$arr, $v) {
return array_merge($arr, (array) $v);
}, array());
You can do
array_merge($arr[0]['T1'], $arr[0][0])
Where $arr is defined as follows:
$arr = [0 => Array
(
'T1' => Array
(
'First' => 'A',
'Second' => 'Apples',
'LastChild' => 'F'
),
0 => Array
(
'LastChildNb' => 23
)
)];
For multiple records in $arr, you can simply cycle over all records and do this merge manually.
However, assuming you're getting the array as a result of a find() method, I suggest you consider using T1__LastChildNb as an alias within the 'fields' of your condition. Simply said, if you have a find like following:
$this->T1->find('all', ['fields' => 'T1.*, (SOME SUBQUERY) AS LastChildNb']);
then modifying it to be
$this->T1->find('all', ['fields' => 'T1.*, (SOME SUBQUERY) AS T1__LastChildNb']);
might be what you're looking for since it will return desired array directly (tested on 2.6).
Let me know if you're interested in more information.

Get first Smarty Array-Element

How can i get the first smarty array element ?
Actually i know how to do this... but i have following issue.
I get a array passed that looks like this
[DATA] => Array
(
[12] => Array
(
[content] => foobar
)
[1] => Array
(
[content] =>
)
[2] => Array
(
[content] =>
)
[3] => Array
(
[content] =>
)
//this is a snipit of {$myVar|#print_r}
this goes down until [11]
For some reason there is no [0] and a [12] at this position.
I don't know if this will allways be 12 but I know it allways be at the first position.
I can't sort this array because there is another array that has the same sortorder and I have to keep this order for later output.
Is there a way to select the first element without using array[0] or array.0 ?
Info: The project im working on uses Smarty 2
EDIT
I would re-index the array if i knew how :)
Since there is now answere after a couple of hours, i solved my problem temporarly.
To solve this, I opened {php} in smarty, got the array I need, splitted it into two arrays (re-indexing them of course so it starts at 0). Than I temp-save pos 0 from each array to a temp array. Override the orig 0 with underscore (_) and than multisort them, put back the original value to 0 and pass them back to $this->_tpl_vars very complicated way. (all inside the tpl)
{php}
// get array data and re-index it
$i=0;
foreach( $this->_tpl_vars['options'] as $option )
{
foreach( $option['DATA'] as $data )
$array[$i][] = $data;
$i++;
}
//delete empty entrys
$i=0;
foreach( $array[1] as $data ){
if(trim($data['content']) != ""){
$s[] = $array[0][$i];
$a[] = $array[1][$i];
}
$i++;
}
//temp save first values
$tmp_s = $s[0];
$tmp_a = $a[0];
//override first values to have a clean sort and keep them values on pos 0
$s[0] = $a[0] = "_";
//sort the arrays
array_multisort($s,$a);
//putting back the original values
$s[0] = $tmp_s;
$a[0] = $tmp_a;
//pass the array back to tpl_vars
$this->_tpl_vars['new_options'][] = $s;
$this->_tpl_vars['new_options'][] = $a;
{/php}
IF in PHP you have:
$smarty->assign(
'myVar',
array('DATA' =>
array(
12 => array('content' => 'first element'),
1 => array('content' => 'second element')
))
);
In Smarty you can use:
{assign var=first value = $myVar.DATA|#key}
{$myVar.DATA.$first.content}
And you will get displayed:
first element
However if in PHP you use:
$data = array(
12 => array('content' => 'first element'),
1 => array('content' => 'second element')
);
next($data);
$smarty->assign(
'myVar',
array('DATA' => $data
)
);
And in Smarty have the same as I showed at the beginning, the result will be:
second element
You would need to call:
reset($data);
after
next($data);
I think you cannot call reset for array in Smarty but I could be wrong.
It's also possible to reset array in Smarty but it's not so easy.
If in PHP you have:
$data = array(
12 => array('content' => 'first element'),
1 => array('content' => 'second element')
);
next($data);
$smarty->assign(
'myVar',
array('DATA' => $data
)
);
In Smarty you could use:
{assign var=$myVar.DATA value=$myVar.DATA|#reset}
{assign var=first value = $myVar.DATA|#key}
{$myVar.DATA.$first.content}
And you will get:
first element
as result
If your data is in array {$data} then using Smarty 3 you can just
{$firstData = $data|reset}

How to sort an array created by the directory_helper in CodeIgniter

So I'm using the directory_map function in the Directory Helper and I'm wondering how I can edit that function (or maybe extend it or something) so that it sorts the multidimensional array it gives me.
Here is the array it currently produces;
Array
(
[publications] => Array
(
[policy_documents] => Array
(
[_careers] => Array
(
[0] => careers.pdf
)
[_background_quality_reports] => Array
(
[0] => industry.pdf
[1] => international.pdf
[2] => departmental_resources.pdf
[3] => contracts.pdf
[4] => research_and_development.pdf
[5] => trade.pdf
)
[_pre_release_access_list] => Array
(
[0] => pre_release_access_list.pdf
)
)
[people] => Array
(
[health] => Array
(
[very_serious_injuries] => Array
(
[_1_january_2013] => Array
(
[0] => 1_january_2013.pdf
)
)
)
[military] => Array
(
[quarterly_manning_report] => Array
(
[_1_january_2013] => Array
(
[0] => 1_january_2013.pdf
)
)
[monthly_manning_report] => Array
(
[_20110201_1_february_2011] => Array
(
[0] => 1_february_2011.xls
[1] => key_points.html
[2] => 1_february_2011.pdf
)
[_20110301_1_march_2011] => Array
(
[0] => 1 March 2011.pdf
)
[_20110501_1_may_2011] => Array
(
[0] => 1 May 2011.pdf
)
[_20110401_1_april_2011] => Array
(
[0] => 1 April 2011.pdf
)
)
)
[civilian] => Array
(
[civilian_personnel_report] => Array
(
[_1_april_2012] => Array
(
[0] => 1_april_2012.pdf
)
[_1_october_2012] => Array
(
[0] => 1_october_2012.pdf
)
[_1_january_2013] => Array
(
[0] => 1_january_2013.pdf
[1] => key_points.html
)
[_1_july_2012] => Array
(
[0] => 1_july 2012.pdf
)
)
)
[search_and_rescue] => Array
(
[monthly] => Array
(
[_1_February_2013] => Array
(
[0] => 1_february_2013.pdf
)
)
[annual] => Array
(
[_2012] => Array
(
[0] => 2012.pdf
)
)
[quarterly] => Array
(
[_q3_2012] => Array
(
[0] => q3_2012.pdf
)
)
)
)
[estate] => Array
(
)
)
)
That's a little messy but you get the idea. Any attempt to wrap a sort() or an asort() around the variable in my model leads to an error. Which is why I think I might have to edit this function or maybe create me a new one...
You have to split up the array sort the files and directories separately since the dir names are in the keys and the file names are in the values.
$dir_map = dir_map_sort(directory_map('folder/name'));
/**
* Sorts the return of directory_map() alphabetically
* directories listed before files
*
* Example:
* a_dir/
* b_dir/
* a_file.dat
* b_file.dat
*/
function dir_map_sort($array)
{
$dirs = array();
$files = array();
foreach ($array as $key => $val)
{
if (is_array($val)) // if is dir
{
// run dir array through function to sort subdirs and files
// unless it's empty
$dirs[$key] = (!empty($array)) ? dir_map_sort($val) : $val;
}
else
{
$files[$key] = $val;
}
}
ksort($dirs); // sort by key (dir name)
asort($files); // sort by value (file name)
// put the sorted arrays back together
// swap $dirs and $files if you'd rather have files listed first
return array_merge($dirs, $files);
}
OR
/**
* Sorts the return of directory_map() alphabetically
* with directories and files mixed
*
* Example:
* a_dir/
* a_file.dat
* b_dir/
* b_file.dat
*/
function dir_map_sort($array)
{
$items = array();
foreach ($array as $key => $val)
{
if (is_array($val)) // if is dir
{
// run dir array through function to sort subdirs and files
// unless it's empty
$items[$key] = (!empty($array)) ? dir_map_sort($val) : $val;
}
else
{
$items[$val] = $val;
}
}
ksort($items); // sort by key
return $items;
}
You can order in SQL select statement (ORDER BY XXX) or in controller use one of these methods at
[1]: http://php.net/manual/en/array.sorting.php php.net

Resources