Multidimensional array looping (PHP) - a better way? - php

Is there a better/more efficient way to loop through this data?
I need to loop through the array data with the 'Name' first and the 'ListID' second but the external API request generates the array as per the code below (the other way round).
// Array Data
$csList = array(
array(
'ListID' => 'BGERFwQTrHoseE4sweebqwyAxuJ9YU',
'Name' => 'Monthly Newsletter Subscribers'
),
array(
'ListID' => 'kHdUQMbELgMyojuATz9Dsbxz3WViVo',
'Name' => 'Special Mailout'
)
);
// Generate Array Varaibles
foreach($csList as $array => $values) {
foreach($values as $k => $v) {
for($i = 1; $i < count($csList); $i++) {
$csListData[$k][] = $v;
}
}
}
// Loop Data
for($i = 0; $i < count($csList); $i++) {
echo $csListData['Name'][$i].'<br>';
echo $csListData['ListID'][$i].'<br>';
}

It's not at all clear why you're rearranging the data. Loop over the array and access whatever keys you want in whatever order you want.
$csList = array(
array(
'ListID' => 'BGERFwQTrHoseE4sweebqwyAxuJ9YU',
'Name' => 'Monthly Newsletter Subscribers'
),
array(
'ListID' => 'kHdUQMbELgMyojuATz9Dsbxz3WViVo',
'Name' => 'Special Mailout'
)
);
foreach ($csList as $item) {
echo $item['Name'].'<br>';
echo $item['ListID'].'<br>';
}

Your inner for loop is useless. You can use the $array key to get your array as wanted :
foreach($csList as $array => $values) {
foreach($values as $k => $v) {
$csListData[$k][$array] = $v;
}
}
// Loop Data
for($i = 0, $c = count($csList); $i <$c; $i++) {
echo '<br>';
echo $csListData['Name'][$i].'<br>';
echo $csListData['ListID'][$i].'<br>';
}
Also, moving the count() out of the check will avoid to count at every iteration of the loop.

// Array Data
$csList = array(
array(
'ListID' => 'BGERFwQTrHoseE4sweebqwyAxuJ9YU',
'Name' => 'Monthly Newsletter Subscribers'
),
array(
'ListID' => 'kHdUQMbELgMyojuATz9Dsbxz3WViVo',
'Name' => 'Special Mailout'
)
);
You can do as follow:
$newCsList = array();
$newCsList = array_map(function ($val){
return array_reverse($val,true);
},$csList);
The result is like:
**Array (
[0] => Array (
[Name] => Monthly Newsletter Subscribers
[ListID] => BGERFwQTrHoseE4sweebqwyAxuJ9YU
)
[1] => Array (
[Name] => Special Mailout
[ListID] => kHdUQMbELgMyojuATz9Dsbxz3WViVo
)
)**
But for taking each element you can do:
$newCsList = array();
$newCsList = array_map(function ($val){
$my_test_ary = array_reverse($val);
echo $my_test_ary['Name'].'<br/>'.$my_test_ary['ListId'];
},$csList);

Related

Count array key that contain specific string

I have an array like that contain key with same name but with number at the end
array example:
Array
(
[field_name0] => name
[field_name1] => sku_package_height
[field_name2] => sku_package_width
[custom_field] => 13
[attribute] => 'test'
[field_name3] => sku_package_length
[field_name4] => sku_package_weight
)
from the example above i want to count how many record that has array key that contain field_name, so the result I want will be 5
you can do this :
$count = 0;
foreach($array as $key => $value){
if(strpos($key,"field_name") > -1){
$count++;
}
}
$count will have number of keys.
You can do it like below:-
<?php
$original_array = Array
(
'field_name0' => 'name',
'field_name1' => 'sku_package_height',
'field_name2' => 'sku_package_width',
'custom_field' => 13,
'attribute' => 'test',
'field_name3' => 'sku_package_length',
'field_name4' => 'sku_package_weight'
);
$search = "field_name";
$counter = 0;
foreach($original_array as $key=> $value){
if(strstr($key,$search)){
$counter = $counter+1;
}
}
echo $counter;
Output:-https://eval.in/704506
Or
<?php
$original_array = Array
(
'field_name0' => 'name',
'field_name1' => 'sku_package_height',
'field_name2' => 'sku_package_width',
'custom_field' => 13,
'attribute' => 'test',
'field_name3' => 'sku_package_length',
'field_name4' => 'sku_package_weight',
);
$search = "field_name";
$counter = 0;
foreach($original_array as $key=> $value){
if(is_numeric(strpos($key,$search))){
$counter = $counter+1;
}
}
echo $counter;
Output:-https://eval.in/704518
Check the isnumeric of the string position "field_name" in key
$i= 0;
foreach($arrayfields as $keys => $values){
if (is_numeric(strpos($keys,"field_name"))){
$i++;
}
}
echo $i;
<?php
$array=array("field_name0"=>"name","field_name1"=>"sku_package_height ","field_name2"=>"sku_package_width","custom_field"=>"13","attribute"=>"test","field_name3"=>"sku_package_length", "field_name4"=>"sku_package_weight");
echo $arraykey= count(preg_grep("/^field_name(\d)+$/",array_keys($array)));
?>

Foreach loop array?

I am trying to create an array using foreach which is used inside an another array.
$team = array();
foreach ($items as $item) {
$team[] = array($item->post_title => $item->post_title, );
}
print_r($team);
$meta_boxes[] = array(
'title' => __( 'Team', 'meta-box' ),
'fields' => array(
array(
'name' => __( 'Select', 'meta-box' ),
'options' => $team,
),
)
);
The options array should be in the format of
'options' => array(
'value1' => ('Label1'),
'value2' => ('Label2'),
),
The print_r output is
Array (
[0] => Array ( [Jessi] => Jessi )
[1] => Array ( [Adam] => Adam )
[2] => Array ( [Babu] => Babu )
)
I am getting output as Array,Array,Array in selectbox for which I am trying to use this for. How do I fix this?
Thanks
Add Key in array [$item->post_title] and assign the values
$team = array();
foreach ($items as $item) {
$team[$item->post_title] = $item->post_title;
}
print_r($team);
Try with -
foreach ($items as $item) {
$team[$item->post_title] = $item->post_title;
}
You can also try like this
$team = array();
foreach ($items as $item) {
$team = array_merge($team,array($item->post_title => $item->post_title));
}

How do I reform this array into a differently structured array

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++;
}

Merge and rearrange nested key/values

I have an array like this:
array(
0 => array(
'name' => 'colors',
'options' => array(
array('name'=>'red', 'price'=>'2'),
array('name'=>'blue', 'price'=>'3')
)
),
1 => array(
'name' => 'sizes',
'options' => array(
array('name'=>'small', 'price'=>'5'),
array('name'=>'large', 'price'=>'10')
)
),
);
I want to merge all of the nested options arrays' name/prices into one, so it'll be like this:
array(
'red' => '2',
'blue' => '3',
'small' => '5',
'large' => '10'
);
I have a feeling this is very simple, but anything I try seems too convoluted. Any help would be appreciated.
...and yes, I just posted almost the same question not too long ago. This is a bit different, and what I meant to ask in the first place - oops, sorry.
I'm not sure if this can be done with internal methods such as array_merge(), array_combine(), etc since your structure seems quite special. But how about iterating over the array and building a new one yourself?
function customRearrange($arr) {
$result = array();
foreach ($arr as $group) {
foreach ($group['options'] as $option) {
// prevents values from being overwritten, uncomment if unwanted
if (!array_key_exists($option['name'], $result))
$result[ $option['name'] ] = $option['price'];
}
}
return $result;
}
You need to decide how you will handle collisions, anyway here is same which will give you right direction:
$newArray = array();
foreach ($array as $i => $item)
foreach ($item['options'] as $j => $option)
$newArray[$option['name']] = $option['price'];
Here's another way, assuming the array has been assigned to the variable $a:
<?php
for ($i = 0; $i < count($a); $i++) {
$key = $a[$i]['name'];
$options = $a[$i]['options'];
for ($j = 0; $j < count($options); $j++) {
$optkey = $options[$j]['name'];
$prices[$optkey] = $options[$j]['price'];
}
}
print_r($prices);
Iterate through "options" in the nested array and create a new array :
<?php
$arr = array(
0 => array(
'name' => 'colors',
'options' => array(
array('name'=>'red', 'price'=>'2'),
array('name'=>'blue', 'price'=>'3')
)
),
1 => array(
'name' => 'sizes',
'options' => array(
array('name'=>'small', 'price'=>'5'),
array('name'=>'large', 'price'=>'10')
)
),
);
$group = array();
foreach($arr as $a){
foreach($a['options'] as $op){
$group[$op['name']] = $op['price'];
}
}
print_r($group);
?>

How do I transform this array into a multi-dimensional array via recursion?

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)
);

Categories