I have an array that looks like this:
[0] => Array
(
[name] => typeOfMusic
[value] => this_music_choice
)
[1] => Array
(
[name] => myMusicChoice
[value] => 9
)
[2] => Array
(
[name] => myMusicChoice
[value] => 8
)
I would like to reform this into something with roughly the following structure:
Array(
"typeOfMusic" => "this_music_choice",
"myMusicChoice" => array(9, 8)
)
I have written the following but it doesn't work:
foreach($originalArray as $key => $value) {
if( !empty($return[$value["name"]]) ){
$return[$value["name"]][] = $value["value"];
} else {
$return[$value["name"]] = $value["value"];
}
}
return $return;
I've tried lots of different combinations to try and get this working. My original array could contain several sets of keys that need converting to arrays (i.e. it's not always going to be just "myMusicChoice" that needs converting to an array) ?
I'm getting nowhere with this and would appreciate a little help. Many thanks.
You just need to loop over the data and create a new array with the name/value. If you see a repeat name, then change the value into an array.
Something like this:
$return = array();
foreach($originalArray as $data){
if(!isset($return[$data['name']])){
// This is the first time we've seen this name,
// it's not in $return, so let's add it
$return[$data['name']] = $data['value'];
}
elseif(!is_array($return[$data['name']])){
// We've seen this key before, but it's not already an array
// let's convert it to an array
$return[$data['name']] = array($return[$data['name']], $data['value']);
}
else{
// We've seen this key before, so let's just add to the array
$return[$data['name']][] = $data['value'];
}
}
DEMO: https://eval.in/173852
Here's a clean solution, which uses array_reduce
$a = [
[
'name' => 'typeOfMusic',
'value' => 'this_music_choice'
],
[
'name' => 'myMusicChoice',
'value' => 9
],
[
'name' => 'myMusicChoice',
'value' => 8
]
];
$r = array_reduce($a, function(&$array, $item){
// Has this key been initialized yet?
if (empty($array[$item['name']])) {
$array[$item['name']] = [];
}
$array[$item['name']][] = $item['value'];
return $array;
}, []);
$arr = array(
0 => array(
'name' => 'typeOfMusic',
'value' => 'this_music_choice'
),
1 => array(
'name' => 'myMusicChoice',
'value' => 9
),
2 => array(
'name' => 'myMusicChoice',
'value' => 8
)
);
$newArr = array();
$name = 'name';
$value = 'value';
$x = 0;
foreach($arr as $row) {
if ($x == 0) {
$newArr[$row[$$name]] = $row[$$value];
} else {
if (! is_array($newArr[$row[$$name]])) {
$newArr[$row[$$name]] = array();
}
array_push($newArr[$row[$$name]], $row[$$value]);
}
$x++;
}
Related
I've an array on php that will return a lot of keys->values, like this:
Array
[0] => Array
(
[value] => 405
[information] => some information1
)
[1] => Array
(
[value] => 500
[information] => some information2
)
[2] => Array
(
[value] => 700
[information] => some information3
)
the values are numbers, i need to collect all the values, check the first one that will be >= $determinedvalue and then return the value "information" for this exactly array, is this even possible? I know i can do this if i create a temp table on my database, but i dont want to.
To be more clearly, when my value is "430" it will return me "some information2".
I've searched a lot on google but by now i dont know if this is even possible.
Appreciate any help.
This is a sample on how to do that. Comments in code can be used to explain the execution.
// Sample Array
$arr = array(
array
(
"value" => 405,
"information" => "some information1"
),
array
(
"value" => 500,
"information" => "some information2"
),
array
(
"value" => 700,
"information" => "some information3"
)
);
// Sample Number
$numberToCheck = 430;
// Sub Array To Assign
$subArray = array();
// Loop Through Outer Array
for ( $i = 0; $i < sizeof($arr); $i++)
{
// If Value In Array > Number Check
if ( $arr[$i]['value'] >= $numberToCheck )
{
$subArray = $arr[$i]; // Assign Sub Array
$i = sizeof($arr); // This is Used to Exit For Loop
}
}
print_r($subArray); // Print
Working runnable code: https://tech.io/snippet/QJ93AwV
Code snippent with comments:
<?php
/**
* Helper class for stable sort alogithms
* #see https://github.com/vanderlee/PHP-stable-sort-functions
* Class StableSort
*/
class StableSort
{
static public function usort(array &$array, $value_compare_func)
{
$index = 0;
foreach ($array as &$item) {
$item = array($index++, $item);
}
$result = usort($array, function ($a, $b) use ($value_compare_func) {
$result = call_user_func($value_compare_func, $a[1], $b[1]);
return $result == 0 ? $a[0] - $b[0] : $result;
});
foreach ($array as &$item) {
$item = $item[1];
}
return $result;
}
}
$array = [
// added for test sorting
[
'value' => 9999,
'information' => 'some information-1',
],
[
'value' => 1200,
'information' => 'some information0',
],
// \added for test sorting
[
'value' => 405,
'information' => 'some information1',
],
// added for test sorting stability
[
'value' => 405,
'information' => 'some information1.2',
],
[
'value' => 405,
'information' => 'some information1.1',
],
// \added for test sorting stability
[
'value' => 500,
'information' => 'some information2',
],
[
'value' => 700,
'information' => 'some information3',
],
];
// sort array
$determinedvalue = 430;
StableSort::usort($array, function ($item1, $item2) {
if ($item1['value'] == $item2['value']) return 0;
return $item1['value'] < $item2['value'] ? -1 : 1;
});
// then select the first element by condition
$res = null;
foreach($array as $v) {
if($v['value'] >= $determinedvalue) {
$res = $v['information'];
break;
}
}
// for testing
print $res;
$number = 430;
$array = Array
[0] => Array
(
[value] => 405
[information] => some information1
)
[1] => Array
(
[value] => 500
[information] => some information2
)
[2] => Array
(
[value] => 700
[information] => some information3
)
$firstArray = $array[0];
$secondArray = $array[1];
$threeArray = $array[2];
function selectValueFromArrayRange ($number, $start, $end, $value, $infomation)
{
$startValue = $start[$value];
$endValue = $end[$value];
if ( in_array($number, range($startValue, $endValue)) ) {
return $end[$infomation];
}
}
selectValueFromArrayRange($number, $firstArray, $secondValue, 'value', 'infomation')
I have an Multidimensional array that takes a similar form to this array bellow.
$shop = array( array( Title => "rose",
Price => 1.25,
Number => 15
),
array( Title => "daisy",
Price => 0.75,
Number => 25,
),
array( Title => "orchid",
Price => 1.15,
Number => 7
)
);
I would like to see if a value I'm looking for is in the array, and if so, return the position of the element in the array.
Here's a function off the PHP Manual and in the comment section.. Works like a charm.
<?php
function recursive_array_search($needle,$haystack) {
foreach($haystack as $key=>$value) {
$current_key=$key;
if($needle===$value OR (is_array($value) && recursive_array_search($needle,$value) !== false)) {
return $current_key;
}
}
return false;
}
Found this function in the PHP docs: http://www.php.net/array_search
A more naive approach than the one showed by Zander, you can hold a reference to the outer key and inner key in a foreach loop and store them.
$outer = "";
$inner = "";
foreach($shop as $outer_key => $inner_array){
foreach($inner_array as $inner_key => $value) {
if($value == "rose") {
$outer = $outer_key;
$inner = $inner_key;
break 2;
}
}
}
if(!empty($outer)) echo $shop[$outer][$inner];
else echo "value not found";
You can use array_map with in_array and return the keys you want
$search = 1.25;
print_r(
array_filter(array_map(function($a){
if (in_array($search, $a)){
return $a;
}
}, $shop))
);
Will print:
Array
(
[0] => Array
(
[Title] => rose
[Price] => 1.25
[Number] => 15
)
)
php >= 5.5
$shop = array( array( 'Title' => "rose",
'Price' => 1.25,
'Number' => 15
),
array( 'Title' => "daisy",
'Price' => 0.75,
'Number' => 25,
),
array( 'Title' => "orchid",
'Price' => 1.15,
'Number' => 7
)
);
$titles = array_column($shop,'Title');
if(!empty($titles['rose']) && $titles['rose'] == 'YOUR_SEARCH_VALUE'){
//do the stuff
}
I have the following challenging array of associative arrays in php.
array(
(int) 0 => array(
'table' => array(
'venue' => 'venue1',
'name' => 'name1'
)
),
(int) 1 => array(
'table' => array(
'venue' => 'venue1',
'name' => 'name2'
)
),
(int) 2 => array(
'table' => array(
'venue' => 'venue2',
'name' => 'name3'
)
),
(int) 3 => array(
'table' => array(
'venue' => 'venue3',
'name' => 'name4'
)
)
)
I want to extract a list of relevant names out based on the venue. I would like to implement a function ExtractNameArray($venue) such that when $venue=='venue1', the returned array will look like array('name1', 'name2')
I have been cracking my head over this. I am starting with $foreach and am stuck. How can this be done in php? Thank you very much.
first, you have to pass the array with the data to the function
second, the name of the function should start with lower character (php conventions)
try this
function extractNameArray($array, $venue) {
$results = array();
foreach($array as $key=>$value) {
if(isset($value['table']['venue'])&&$value['table']['venue']==$venue) {
isset($value['table']['name']) && $results[] = $value['table']['name'];
}
}
return $results;
}
function ExtractNameArray($venue)
{
$array = array(); // your array
$return_array = array();
foreach($array as $arr)
{
foreach($arr['table'] as $table)
{
if($table['venue'] == $venue)
{
$return_array[]['name'] = $table['name'];
}
}
}
return $return_array;
}
You must define $array with you array. Good Luck
Here are two example of the format of the Arrays, full code and array content in my code below.
ARRAY 1
[
'version' => '1.0',
'injuries' => [
'timestamp' => 1377702112,
'week' => 1,
'injury' => [
[
'status' => 'Questionable',
'id' => '10009',
'details' => 'Shoulder'
],
[
'status' => 'Questionable',
'id' => '10012',
'details' => 'Ankle'
]
]
]
]
ARRAY 2
[
'version' => '1.0',
'players' => [
'timestamp' => 1377676937,
'player' => [
[
'position' => 'TMDL',
'name' => 'Bills, Buffalo',
'id' => '0251',
'team' => 'BUF'
],
[
'position' => 'TMDL',
'name' => 'Colts, Indianapolis',
'id' => '10009',
'team' => 'IND'
]
]
]
]
What I need to do is sort through both Arrays and finding matching values for the ID key. I need to then combine the values of both arrays into one array so I can print it out on screen. There is two API's provided, one for the injuries report with a player [id] key and the other for the Players Information with [id] keys. Here is how far I have gotten on this problem:
<?php
function injuries_report() {
//Get json files
$injuryData = file_get_contents('http://football.myfa...=1&callback=');
$playerData = file_get_contents('http://football.myfa...L=&W=&JSON=1');
//format json data into an array
$obj1 = json_decode($injuryData, true);
$obj2 = json_decode($playerData, true);
//return print_r($obj1); //print obj1 to see output
return print_r($obj2); //print obj2 to see output
}
?>
<!--get injuries report -->
<pre><?php injuries_report(); ?></pre>
Here's the working code, thanks to Chris:)
$injuryData = file_get_contents('http://football.myfantasyleague.com/2013/export?TYPE=injuries&L=&W=&JSON=1&callback=');
$array1 = json_decode($injuryData, true);
$playerData = file_get_contents('http://football.myfantasyleague.com/2013/export?TYPE=players&L=&W=&JSON=1');
$array2 = json_decode($playerData, true);
function map($x) {
global $array1;
if(isset($x['id'])) {
$id = $x['id'];
$valid = array_filter($array1['injuries']['injury'], create_function('$injury', 'return $injury["id"] == "' . $id .'";'));
if(count($valid) > 0) {
$x = array_merge($x, array_shift($valid));
}
}
return $x;
}
$output = array_map('map', $array2['players']['player']);
echo "<pre>";
print_r($output);
echo "</pre>";
Ok, I'm assuming you want to add injuries to players. The output will be the list of players, with the injuries added (where they apply)
$output = array_map(function($x) use ($array1) {
$id = $x['id'];
$valid = array_filter($array1['injuries']['injury'], function($injury) use ($id) {
return $injury['id'] == $id;
});
if(count($valid) > 0) {
$x = array_merge($x, $valid[0]);
}
return $x;
}, $array2['players']['player']);
print_r($output);
The output is this:
Array
(
[0] => Array
(
[position] => TMDL
[name] => Bills, Buffalo
[id] => 0251
[team] => BUF
)
[1] => Array
(
[position] => TMDL
[name] => Colts, Indianapolis
[id] => 10009
[team] => IND
[status] => Questionable
[details] => Shoulder
)
)
php 5.2
Edit The latest working version:
Oh you are using php 5.2. Here is a php 5.2 version, but it less pretty than the code before:
$injuryData = file_get_contents('http://football.myfantasyleague.com/2013/export?TYPE=injuries&L=&W=&JSON=1&callback=');
$array1 = json_decode($injuryData, true);
$playerData = file_get_contents('http://football.myfantasyleague.com/2013/export?TYPE=players&L=&W=&JSON=1');
$array2 = json_decode($playerData, true);
function map($x) {
global $array1;
if(isset($x['id'])) {
$id = $x['id'];
$valid = array_filter($array1['injuries']['injury'], create_function('$injury', 'return $injury["id"] == "' . $id .'";'));
if(count($valid) > 0) {
$x = array_merge($x, array_shift($valid));
}
}
return $x;
}
$output = array_map('map', $array2['players']['player']);
print_r($output);
The $array1 is global here. Check it here: http://pastebin.com/N3RqtfzN
So my example inputs are
$example_1 = Array (
0 => Array (
'category' => 'body',
'sub-category' => 'intro',
'id' => 'header',
'copy' => 'Hello',
),
1 => Array (
'category' => 'body',
'sub-category' => 'intro',
'id' => 'footer',
'copy' => 'Bye',
),
);
$example_2 = Array (
0 => Array (
'category' => 'body',
'sub-category' => 'intro',
'sub-sub-category' => 'header',
'sub-sub-child-category' => 'left',
'id' => 'title',
'copy' => 'Hello',
),
1 => Array (
'category' => 'body',
'sub-category' => 'intro',
'sub-sub-category' => 'footer',
'sub-sub-child-category' => 'right',
'id' => 'title',
'copy' => 'Bye',
),
);
I want to transform it into
$example_output_1 = Array (
'body' => Array (
'intro' => Array (
'header' => Array (
'title' => 'Hello',
),
'footer' => Array (
'title' => 'Bye',
),
),
),
);
$example_output_2 = Array (
'body' => Array (
'intro' => Array (
'header' => Array (
'left' => Array (
'title' => 'Hello',
),
),
'footer' => Array (
'right' => Array (
'title' => 'Bye',
)
),
),
),
);
Note the depth of the array is dynamic (it is not set - only by the time it hits 'copy' does it indicate the depth of the array).
I am having problems trying to get the recursion correctly. The basic but very rough algorithm I had was to
- Loop through the Row
- Loop through the contents of the Row
- When the index is "copy" then the final value is current value.
- Then build the array
I managed to get it to process for ONLY one row of the array but it was very messy and kinda patchy, so I got a feeling I really need to start from scratch.
Updated: Attached embarrassing Code as requested (don't scream! ;p)
function buildArray($row, $start = true) {
if ($start) {
$result = array();
}
if ( ! is_array($row) ) {
return $row;
}
// Get the first element of the array include its index
$cellValue = null;
$colId = null;
foreach($row AS $index => $value) {
$cellValue = $value;
$colId = $index;
break;
}
// Reduce the array by one
$tempRow = $row;
$temp = array_shift($tempRow);
if ($colId == 'copy') {
$result[$cell] = buildArray($cellValue, $locale, false);
} else {
$result[$cell] = buildArray($tempRow, $locale, false);
}
return $result;
}
Any help will be greatly appreciated.
Should be pretty straightforward:
$originalArray = array(); // <-- should contain your values
$newArray = array();
foreach( $originalArray as $item )
{
$category = $item['category'];
$subcategory = $item['sub-category'];
if ( empty( $newArray[$category] ) )
{
$newArray[$category] = array();
}
if ( empty( $newArray[$category][$subcategory] ) )
{
$newArray[$category][$subcategory] = array();
}
$newArray[$category][$subcategory][$item['id']] = $item['copy'];
}
See it here in action: http://codepad.viper-7.com/9bDiLP
Update: Now that you've specified that you need unlimited recursion, here's a shot at that:
$originalArray = array(); // <-- Your values go here
$newArray = array();
foreach ( $originalArray as $item )
{
$inception = &$newArray; // http://www.imdb.com/title/tt1375666/
foreach ( $item as $key => $val )
{
if ( $key != 'id' )
{
if ( empty($inception[$val]) )
{
$inception[$val] = array();
}
$inception = &$inception[$val];
}
else
{
$inception[ $val ] = $item['copy'];
break;
}
}
}
...and here's the demo: http://codepad.viper-7.com/F9hY7h
This can be solved iteratively, because the recursion would only happen at the tail end of your function. The following code is the simplification. It builds a new layered array while it iterates over the old.
After transforming each each entry it gets merged using array_merge_recursive.
function transform($a)
{
// create new array and keep a reference to it
$b = array(); $cur = &$b;
foreach ($a as $key => $value) {
if ('id' === $key) {
// we're done, add value to the array built so far using id and copy
$cur[$value] = $a['copy'];
break;
} else {
// create one more level
$cur[$value] = array();
// and update the reference
$cur = &$cur[$value];
}
}
// all done
return $b;
}
// $example_2 is your multi-dimensional array
$merged = call_user_func_array('array_merge_recursive',
array_map('transform', $example_2)
);