PhP multidimensional array to individual array - php

I have a multidimensional array which I want to convert to individual arrays.
Original array is
$hos_pabsl = array(
0 =>
array(
'tile_id' => '1',
'tile_type' => '4',
'title' => 'Introduction',
'topicNum' => '1',
'topicTitle' => 'Introduction',
'subNum' => NULL,
),
1 =>
array(
'tile_id' => '2',
'tile_type' => '9',
'title' => 'Beer',
'topicNum' => '2',
'topicTitle' => 'Beer',
'subNum' => NULL,
),
2 =>
array(
'tile_id' => '3',
'tile_type' => '4',
'title' => 'Methods of Brewing',
'topicNum' => '2',
'topicTitle' => 'Beer',
'subNum' => NULL,
),
3 =>
array(
'tile_id' => '4',
'tile_type' => '11',
'title' => 'Beer Styles',
'topicNum' => '2',
'topicTitle' => 'Beer',
'subNum' => '',
),
);
I want to convert this array into individual arrays named 'tile_id' , 'tile_type' , ....
Currently I am doing it the following way !
$tile_id = [];
$tile_type = [];
$title = [];
$topicNum = [];
$topicTitle= [];
$subNum = [];
foreach($hos_pabsl as $val){
array_push($tile_id, $val['tile_id']);
array_push($tile_type, $val['tile_type']);
array_push($title, $val['title']);
array_push($topicNum, $val['topicNum']);
array_push($topicTitle, $val['topicTitle']);
array_push($subNum, $val['subNum']);
}
Problem 1: IS this the most efficient way (in terms of speed) to do this operation?
Problem 2:
The $hos_pabsl array's index (or keys) are always going to be sequential. However, my problem is that for second array (at level 2 OR $hos_pabsl[0]) the index (or keys) might increase or decrease.
E.g. all arrays in might have only 2 items 'tile_id' & 'title'. OR might have one extra item 'description'. So how can I make the above operation dynamic ?
To Solve problem 2, I have thought of using array_keys to extract names first $names = array_keys($hos_pabsl[0]) then using those names as array names like ${$names[0]} =[]. Again I don't think this is the right/efficient way to do this.
Any guidance on this would be really appreciated.

If you're running PHP 5.5, then you can use array_column()
$tile_id = array_column($hos_pabsl, 'tile_id');
$tile_type = array_column($hos_pabsl, 'tile_type');
... etc
for versions of PHP earlier than 5.5, you can use array_map()
$tile_id = array_map(
function ($value) { return $value['tile_id']; }, $hos_pabsl
);
$tile_type = array_map(
function ($value) { return $value['tile_type']; }, $hos_pabsl
);
... etc

To go with Mark Baker's answer since I was already typing it:
foreach(array_keys(reset($hos_pabsl)) as $key) {
$$key = array_column($hos_pabsl, $key);
}

In terms of performance if the array is huge using a for instead of a foreach it will be faster.
$tile_id = array();
$tile_type = array();
$title = array();
$topicNum = array();
$topicTitle = array();
$subNum = array();
$hos_pabsl_sz = count($hos_pabsl);
for ($i = 0; $i < $hos_pabsl_sz; ++$i ) {
$tile_id[$i] = $hos_pabsl[$i]['tile_id'];
$tile_type[$i] = $hos_pabsl[$i]['tile_type'];
$title[$i] = $hos_pabsl[$i]['title'];
$topicNum[$i] = $hos_pabsl[$i]['topicNum'];
$topicTitle[$i] = $hos_pabsl[$i]['topicTitle'];
$subNum[$i] = $hos_pabsl[$i]['subNum'];
}

Related

sorting a multi dimensional array in php

I have an array of arrays, as such
$statuses = array(
[0] => array('id'=>10, 'status' => 'active'),
[1] => array('id'=>11, 'status' => 'closed'),
[2] => array('id'=>12, 'status' => 'active'),
[3] => array('id'=>13, 'status' => 'stopped'),
)
I want to be able to make a new array of arrays and each of those sub arrays would contain the elements based on if they had the same status.
The trick here is, I do not want to do a case check based on hard coded status names as they can be random. I want to basically do a dynamic comparison, and say "if you are unique, then create a new array and stick yourself in there, if an array already exists with the same status than stick me in there instead". A sample result could look something like this.
Ive really had a challenge with this because the only way I can think to do it is check every single element against every other single element, and if unique than create a new array. This gets out of control fast if the original array is larger than 100. There must be some built in functions that can make this efficient.
<?php
$sortedArray = array(
['active'] => array(
array(
'id' => 10,
'status' => 'active'
),
array(
'id' => 12,
'status' => 'active'
)
),
['closed'] => array(
array(
'id' => 11,
'status' => 'active'
)
),
['stopped'] => array(
array(
'id' => 13,
'status' => 'active'
)
),
)
$SortedArray = array();
$SortedArray['active'] = array();
$SortedArray['closed'] = array();
$SortedArray['stopped'] = array();
foreach($statuses as $Curr) {
if ($Curr['status'] == 'active') { $SortedArray['active'][] = $Curr; }
if ($Curr['status'] == 'closed') { $SortedArray['closed'][] = $Curr; }
if ($Curr['status'] == 'stopped') { $SortedArray['stopped'][] = $Curr; }
}
You can also do it with functional way though it's pretty the same like Marc said.
$sorted = array_reduce($statuses, function($carry, $status) {
$carry[$status['status']][] = $status;
return $carry;
}, []);

PHP Explode String Into Multiple Arrays

I have the following string: "1,3,4,7" which I need to explode into an Array in the following format:
$data = array(
array(
'id' => 1
),
array(
'id' => 3
),
array(
'id' => 4
),
array(
'id' => 7
),
);
This seems to be causing me a lot more pain than I'd have thought. Can anyone kindly assist please?
You can use a combination of array_map() and explode(): First you create an array with the values and than you map all these values to the format you need in a new array.
Something like:
$vals = "1,3,4,7";
$map = array_map(function($val) {
return array('id' => $val);
}, explode(',', $vals));
var_dump($map);
An example.
Firstly you explode the string to get the values in an array. Then you iterate through the array and set the data as array to another array
$string = "1,2,3,4";
$array = explode(",", $string);
$data = array();
foreach($array as $arr){
$data[] = array('id' => $arr);
}
<?php
$myArray=explode(",","1,3,5,7");
$result=array();
foreach($myArray as $key=>$arr)
{
$result[$key]['id']=$arr;
}
print_r($result);
?>
Here is a thinking-outside-the-box technique that doesn't require a loop or iterated function calls.
Form a valid query string with the desired structure and parse it. The empty [] syntax will generate the indexes automatically.
Code: (Demo)
$vals = "1,3,4,7";
$queryString = 'a[][id]=' . str_replace(',', '&a[][id]=', $vals);
parse_str($queryString, $output);
var_export($output['a']);
Output:
array (
0 =>
array (
'id' => '1',
),
1 =>
array (
'id' => '3',
),
2 =>
array (
'id' => '4',
),
3 =>
array (
'id' => '7',
),
)

How to replace every value with a customized one inside this associative array?

I am new to PHP. Sorry if this sounds simple.
I have this PHP associative array:
$X = array(
'Model1' => '6',
'Model2' => '5',
'Model3' => '1'
);
I want to convert it to look like this:
$Y = array(
'Model1' => 'prefix_Model1_postfix',
'Model2' => 'prefix_Model2_postfix',
'Model3' => 'prefix_Model3_postfix'
);
The value in each converted record is replaced with a prefix, then followed by the key, then followed by a postfix. How can this be done? Thank you very much. Is foreach a good start?
Yes, you can do it easily with foreach:
$arr = array("Model1" => 6, "Model2" => 5, "Model3" => 1);
$prefix = "prefix_";
$postfix = "_postfix";
foreach($arr as $key => $val){
$arr[$key] = $prefix.$key.$postfix;
}
print_r($arr);
DEMO
you can also use array_walk:
array_walk($x, function($val,$key) use(&$x) {
$x[$key] = 'prefix_' . $key . '_postfix';
});
A different way to do with built-in function and closures:
<?php
$data = array(
'Model1' => '6',
'Model2' => '5',
'Model3' => '1',
);
$data = array_map(function($data){
return "prefix_Model{$data}_postfix";
}, $data);
var_dump($data);
?>
DEMO

Get key of multidimensional array?

For example, I have multidimensional array as below:
$array = array (
0 =>
array (
'id' => '9',
'gallery_id' => '2',
'picture' => '56475832.jpg'
),
1 =>
array (
'id' => '8',
'gallery_id' => '2',
'picture' => '20083622.jpg'
),
2 =>
array (
'id' => '7',
'gallery_id' => '2',
'picture' => '89001465.jpg'
),
3 =>
array (
'id' => '6',
'gallery_id' => '2',
'picture' => '47360232.jpg'
),
4 =>
array (
'id' => '5',
'gallery_id' => '2',
'picture' => '4876713.jpg'
),
5 =>
array (
'id' => '4',
'gallery_id' => '2',
'picture' => '5447392.jpg'
),
6 =>
array (
'id' => '3',
'gallery_id' => '2',
'picture' => '95117187.jpg'
)
);
How can I get key of array(0,1,2,3,4,5,6)?
I have tried a lot of examples, but nothing has worked for me.
This is quite simple, you just need to use array_keys():
$keys = array_keys($array);
See it working
EDIT For your search task, this function should do the job:
function array_search_inner ($array, $attr, $val, $strict = FALSE) {
// Error is input array is not an array
if (!is_array($array)) return FALSE;
// Loop the array
foreach ($array as $key => $inner) {
// Error if inner item is not an array (you may want to remove this line)
if (!is_array($inner)) return FALSE;
// Skip entries where search key is not present
if (!isset($inner[$attr])) continue;
if ($strict) {
// Strict typing
if ($inner[$attr] === $val) return $key;
} else {
// Loose typing
if ($inner[$attr] == $val) return $key;
}
}
// We didn't find it
return NULL;
}
// Example usage
$key = array_search_inner($array, 'id', 9);
The fourth parameter $strict, if TRUE, will use strict type comparisons. So 9 will not work, you would have to pass '9', since the values are stored as strings. Returns the key of the first occurence of a match, NULL if the value is not found, or FALSE on error. make sure to use a strict comparison on the return value, since 0, NULL and FALSE are all possible return values and they will all evaluate to 0 if using loose integer comparisons.
Try this , I think it will help you.
foreach ($array as $key=>$value)
{
echo $key.'<br/>';
echo $value['id'].'<br/>';
echo $value['gallery_id'].'<br/>';
echo $value['picture'].'<br/><br/>';
}
sometimes it is to easy to find ;)
array_keys($array);
array_keys
Probably http://php.net/manual/en/function.array-keys.php ?
Convert your double dimensional array on your own:
$tmp = null
foreach($array as $key => $value) {
$tmp[] = $key;
}
print_r($tmp);
You mean something like this:
function getKeys($array)
{
$resultArr = array();
foreach($array as $subArr) {
$resultArr = array_merge($resultArr, $subArr);
}
return array_keys($resultArr);
}

How to extract data out of a specific PHP array

I have a multi-dimensional array that looks like this:
The base array is indexed based on category ids from my catalog.
$cat[category_id]
Each base array has three underlying elements:
['parent_id']
['sort_order']
['name']
I want to create a function that allows us to create a list of category_id's and names for a given parent_category_id in the correct sort order. Is this possible? Technically it is the same information, but the array is constructed in a weird way to extract that information.
Here is an example definition for the array:
$cat = array();
$cat[32]['parent_id']= 0;
$cat[32]['sort_order']= 1;
$cat[32]['name']= 'my-category-name1';
$cat[45]['parent_id']= 0;
$cat[45]['sort_order']= 0;
$cat[45]['name']= 'my-category-name2';
$cat[2]['parent_id']= 0;
$cat[2]['sort_order']= 2;
$cat[2]['name'] = "my-category-name3";
$cat[3]['parent_id']= 2;
$cat[3]['sort_order']= 1;
$cat[3]['name'] = "my-category-name4";
$cat[6]['parent_id']= 2;
$cat[6]['sort_order']= 0;
$cat[6]['name'] = "my-category-name5";
Assuming it's something of this sort:
$ary = Array(
0 => Array(
'parent_category_id' => null,
'sort_order' => 0,
'name' => 'my-category-name0'
),
1 => Array(
'parent_category_id' => 0,
'sort_order' => 1,
'name' => 'my-category-name1'
),
2 => Array(
'parent_category_id' => 0,
'sort_order' => 2,
'name' => 'my-category-name2'
),
3 => Array(
'parent_category_id' => null,
'sort_order' => 0,
'name' => 'my-category-name3'
),
4 => Array(
'parent_category_id' => 3,
'sort_order' => 0,
'name' => 'my-category-name4'
)
);
You can use a combination of a foreach and usort to achieve what you're going for.
// #array: the array you're searchign through
// #parent_id: the parent id you're filtering by
function getFromParent($array, $parent_id){
$result = Array();
foreach ($array as $category_id => $entry){
if ($entry['parent_category_id']===$parent_id)
$result[$category_id] = $entry;
}
usort($result,create_function('$a,$b','return ($a["sort_order"]>$b["sort_order"]?1:($b["sort_order"]<$a["sort_order"]?-1:0));'));
return $result;
}
var_export(getFromParent($ary,0));
EDIT Sorry, fixed some syntax errors. Tested, and works (at least to result in what I was intending)
EDITv2 Here's the raw output from the above:
array (
0 =>
array (
'parent_category_id' => 0,
'sort_order' => 1,
'name' => 'my-category-name1',
),
1 =>
array (
'parent_category_id' => 0,
'sort_order' => 2,
'name' => 'my-category-name2',
),
)
(Used var_export just for you #FelixKling)
EDITv3 I've updated my answer to go along with the OP's update. I also now make it retain the original "category_id" values in the result array.
First you create an empty array, it will be used to store your result.
$result = array();
You need to iterate through your initial array, you can use foreach().
Then, given your parent_category_id simply use an if statement to check whether it's the given id or not.
If it is, just construct and push your result to your $result array.
Use any of the sort functions you like
Use the magic return $result;
You're done.
function returnSortedParents($categories, $target_parent){
$new_list = array();
foreach($categories as $index => $array){
//FIND ONLY THE ELEMENTS MATCHING THE TARGET PARENT ID
if($array['parent_category_id']==$target_parent){
$new_list[$index = $array['sort_order'];
}
return asort($new_list); //SORT BASED ON THE VALUES, WHICH IS THE SORTING ORDER
}

Categories