Multidimensional array and array_push? - php

I have a huge multidimensional array, let's name it $big_array.
In addition I have this set of data that I have to put into above array:
$input = array('one','two','three','four');
That's what I need to push into $big_array (based on $input from above):
$value = array(
'id' => $number,
'title' => 'foo',
'type' => 'options',
'options' => array('one','two','three','four'),
'page' => 'font_manager',
);
array_push($big_array, $value);
$big_array structure looks like this:
$big_array = array(
(...)
array(
'id' => 'Bar',
'title' => 'Foo',
'type' => 'select',
'page' => 'font_manager',
),
array(
'id' => 'ss_font',
'title' => __("Main font:",'solidstyle_admin'),
'type' => 'select',
'page' => 'font_manager',
'description' => __("This font will be used for all pages.",'solidstyle_admin'),
'default' => '',
'options' => array(
'option1' => 'option1',
'option2' => 'option12,
),
),
(...)
);
What I exactly want to do will look like that if it will be possible to include loops in arrays (yes, I know how wrong is that, just trying to explain it better):
$input = array('one','two','three','four');
$value = array(
'id' => $number,
'title' => 'foo',
'type' => 'options',
'options' => array(
foreach($input as $number) {
echo $number.',';
};
),
'page' => 'font_manager',
);

I think what you are going for is getting
$input = array('one','two','three','four');
inserted into
$value = array(
'id' => $number,
'title' => 'foo',
'type' => 'options',
'page' => 'font_manager',
);
so that it looks like this:
$value = array(
'id' => $number,
'title' => 'foo',
'type' => 'options',
'options' => array('one','two','three','four'),
'page' => 'font_manager',
);
and can then be pushed onto $bigArray . If that is the case, it should be as simple as
$input = array('one','two','three','four');
$value = array(
'id' => $number,
'title' => 'foo',
'type' => 'options',
'page' => 'font_manager',
);
$value['options'] = $input;
$bigArray[] = $value; // equivalent to array_push($bigArray, $value);
If I misunderstood your goal, please let me know.
edit: If you are going for something like this
$value = array(
'id' => $number,
'title' => 'foo',
'type' => 'options',
'options' => array('one,two,three,four'),
'page' => 'font_manager',
);
then it you would just change
$value['options'] = $input;
to
$value['options'] = implode(",",$input);

Have a look at the code below. I have commented it so you can understand what I'm doing.
$input = array('one','two','three','four');
// set the base info here, i.e., info that is common to each push
$baseInfo = array(
'title' => 'foo',
'type' => 'options',
'page' => 'font_manager',
);
// now loop
foreach($input as $number) {
// fill in base info with data that is specific to this iteration
$baseInfo['id'] = $number;
$baseInfo['options'] = $input;
// do the push
array_push($big_array, $baseInfo);
}
I'm not entirely sure I got your question correct. If you were asking something else, please clarify and I will edit my answer.

There are a few ways you could emulate the foreach loop at $array['options']— the simplest would be to define a function elsewhere that does that, and then return that options array! Like:
function return_array_options($input) {
$array = array();
foreach($input as $number) {
$array[] = $number
// or, $array['option'.$number] = $number
};
return $array;
}
Then elsewhere in your code you can use this function:
$my_array = array();
$my_array['options'] = return_array_options(array(1,2,3,4));
With programming, it's always better to break things down into solutions to smaller problems that you then combine.
Also, check out PHP's functional programming functions, like array_map(), and array_filter(). They help to transform things just like a loop woud, but without actually using a loop. So, they are syntatically more flexible in some ways.

If i understand well. You wish to get this :
$input = array('one','two','three','four');
$value = array(
'id' => $number,
'title' => 'foo',
'type' => 'options',
'options' => array(
foreach($input as $number) {
echo $number.',';
};
),
'page' => 'font_manager',
);
And to push it into $big_array, am i right ?
Then the solution is pretty simple.
$input = array('one','two','three','four');
$value = array(
'id' => $number,
'title' => 'foo',
'type' => 'options',
'options' => array(
),
'page' => 'font_manager',
);
Build your array. Then your loop :
foreach($input as $number)
{
$value['options'][] = $number;
}
If you wan to add $input "as is", you may do
$value['options'] = $input;
If you want to have 'one' => 'one'
foreach($input as $number)
{
$value['options'][$number] = $number;
}
It will produce the exact same result than a loop, withouth the loop overhead.
And finally :
array_push($big_array, $value);

Related

Combine and build array with foreach php

I need to build a multidimensional array using foreach
There is an array with the names of social networks social_array()
the result should be like that:
array(
'type' => 'textfield',
'heading' => 'social_label1',
'param_name' => 'social_name1',
'description' => '',
'edit_field_class' => 'vc_col-sm-4 vc_column-with-padding',
'group' => __('Social', 'AS')
),
array(
'type' => 'textfield',
'heading' => 'social_label2',
'param_name' => 'social_name2',
'description' => '',
'edit_field_class' => 'vc_col-sm-4 vc_column-with-padding',
'group' => __('Social', 'AS')
),
...
etc
The problem is that my code gives me only one result, the last
foreach ( social_array() as $icon => $value ) :
$k = array('type', 'heading', 'param_name', 'description', 'edit_field_class', 'group');
$v = array('textfield', $value['label'], $icon, '', 'vc_col-sm-4 vc_column-with-padding', 'Social');
$c = array_combine($k, $v);
$attributes['params'] = $c;
endforeach;
vc_add_params( 'profile_card', $attributes ); // Note: base for element
Social if needed
function social_array(){
return array(
'facebook' => array('label' => __('Facebook','AS7'), 'type' => 'text' ),
'behance' => array('label' => __('Behance','AS7'), 'type' => 'text' ),
'weibo' => array('label' => __('Weibo','AS7'), 'type' => 'text' ),
'renren' => array('label' => __('Renren','AS7'), 'type' => 'text' ),
'dropbox' => array('label' => __('Dropbox','AS7'), 'type' => 'text' ),
'bitbucket' => array('label' => __('Bitbucket','AS7'), 'type' => 'text' ),
'trello' => array('label' => __('Trello','AS7'), 'type' => 'text' ),
'odnoklassniki' => array('label' => __('Odnoklassniki','AS7'), 'type' => 'text' ),
'vk' => array('label' => __('VKontakte','AS7'), 'type' => 'text' ),
);
}
You'll need 2 foreach loops for this because the first foreach loop gives you all the arrays inside it. then you need to access each array and loop over it.
foreach ( social_array() as $array) :
foreach ( $array as $icon => $value ):
//Do something with $icon and its $value
endforeach;
endforeach;
$attributes['params'] = $c;
This is the problem, on any cycle you're setting this value to $c, so in the last cycle you're setting $attributes to the latest $c.
If you want $attributes['params'] to contain all the arrays you need to use this syntax:
$attributes['params'][] = $c;
OR the same but with function call:
array_push($attributes['params'], $c);
maybe someone will come in handy this piece.
The working option is below.
The task was to dynamically add many of the same type of fields in the shortcode settings via Visual Composer and the vc_add_params() function
$attributes = array();
foreach ( social_array() as $icon => $value ) :
$k = array('type', 'heading', 'param_name', 'description', 'edit_field_class', 'group');
$v = array('textfield', $value['label'], 'as_'.$icon, '', 'vc_col-sm-4 vc_column-with-padding', 'Social');
$c = array_combine($k, $v);
$attributes[] = $c;
endforeach;
vc_add_params( 'as_profile_card', $attributes ); // Note: base for element

PHP if statement inside an array

I'm trying to write the below array if a value is set. How can I do this inside of an array? I know I could use a ternary operator but i'm not sure how.
array(
'name' => 'extraFields',
'attributes' => array(
'name' => 'portal',
),
if($Value === 1){
//Need to write the below when value is true
array(
'name' => 'portal',
'value'=> '',
'attributes' => array(
'id' => '1',
'value'=> 'testportal',
),
),
}
),
You cannot intersect a definition of an array with a conditional statement. What you need to do instead is to define your array first and then do an if statement which will add to the array. It's not entirely clear at what level of your array you want to add the conditional content, so I'll show it on a simplified example:
$value = 1;
$myArray = array(
'name' => 'Joe',
'kids' => array(
'name' => 'Mary',
),
);
if ($value === 1) {
$myArray['kids']['hobbies'] = 'kite flying';
}
After this, the variable $myArray will have the following content:
array(
'name' => 'Joe',
'kids' => array(
'name' => 'Mary',
'hobbies' => 'kite flying',
),
)
Where exactly you need to put your conditional data depends on the full structure of your array, but the idea is you access the parts you want through indices.
Edit: in case you can just add the needed subarray at the end of your array, you can utilize array_push.
There is 3 variants to do this:
// Variant 1
// Anonymous function, variables from the parent scope
$Value = 1;
$arr = array(
'name' => 'extraFields',
'attributes' => array(
'name' => 'portal',
),
'ifArray' => function() use ($Value) {
if ($Value == 1)
return array(
'name' => 'portal',
'value'=> '',
'attributes' => array(
'id' => '1',
'value'=> 'testportal',
),
);
}
);
print_r($arr['ifArray']());
// Variant 2
// Anonymous function, variable assignment
$arr = array(
'name' => 'extraFields',
'attributes' => array(
'name' => 'portal',
),
'ifArray' => function($Value) {
if ($Value == 1)
return array(
'name' => 'portal',
'value'=> '',
'attributes' => array(
'id' => '1',
'value'=> 'testportal',
),
);
}
);
$Value = 1;
print_r($arr['ifArray']($Value));
// Variant 3
// Ternar operator
$Value = 1;
$arr = array(
'name' => 'extraFields',
'attributes' => array(
'name' => 'portal',
),
'ifArray' => $Value != 1 ? null : array(
'name' => 'portal',
'value'=> '',
'attributes' => array(
'id' => '1',
'value'=> 'testportal',
)
)
);
print_r($arr['ifArray']);
However, the variant that El_Vanja suggested, might be more clear than those three.

Recursive replace one array with specific key with another arrays

I have an array where all arrays where key type == 'foo' must be replaced by a custom arrays.
Basically I need to find a specific array and then replace it with other arrays.
The issue here you can easily replace one array but when you insert numbers of arrays you are shifting keys so the next array type == 'foo' will not be replaced
Any help would be appreciated.
Here's what I have:
$array = array(
array(
'options' => array(
array(
'type' => 'foo'
),
array(
'type' => 'foo'
),
array(
'type' => 'bar'
)
)
),
array(
'options' => array(
array(
'type' => 'bar'
),
array(
'type' => 'bar'
),
array(
'type' => 'foo'
)
)
),
);
And I have an array which should replace any array where type == 'foo'
$array_foo = array(
array(
'type' => 'custom'
),
array(
'type' => 'custom_2'
),
array(
'type' => 'anything'
),
);
Here is the desired output:
$array = array(
array(
'options' => array(
array(
'type' => 'custom'
),
array(
'type' => 'custom_2'
),
array(
'type' => 'anything'
),
array(
'type' => 'custom'
),
array(
'type' => 'custom_2'
),
array(
'type' => 'anything'
),
array(
'type' => 'bar'
)
)
),
array(
'options' => array(
array(
'type' => 'bar'
),
array(
'type' => 'bar'
),
array(
'type' => 'custom'
),
array(
'type' => 'custom_2'
),
array(
'type' => 'anything'
),
)
),
);
Thank you.
Here's a way using 2 nested foreach loops and array_merge() with a temporary array:
// Pass the array by reference
foreach ($array as &$sub) {
// Temporary array
$new_options = [];
// Loop through options
foreach ($sub['options'] as $opt) {
// if type foo: replace by $array_foo items
if ($opt['type'] == 'foo') {
$new_options = array_merge($new_options, $array_foo);
// else, keep original item
} else {
$new_options[] = $opt;
}
}
// replace the options
$sub['options'] = $new_options;
}
And check the output:
echo '<pre>' . print_r($array, true) . '</pre>';
See also Passing by Reference
According to a previous post, the code for changing could be done in a similar fashion to the following code:
$base = array("orange", "banana", "apple", "raspberry");
$replacements = array(0 => "pineapple", 4 => "cherry");
$replacements2 = array(0 => "grape");
$basket = array_replace($base, $replacements, $replacements2);
print_r($basket);
So with your method instead of having numbers or indexes, I think you might be able to get away with writing down foo instead to get the replacement to work properly.
The other thing you might look into is array merge-recursive which can be found at: http://php.net/array_merge_recursive
The problem you stated here looks similar to this post: PHP Array Merge two Arrays on same key
I hope this helps you.

How to walk down array tree adding new keys to same level?

Firs off, I am struggling to phrase the questions correctly... so bear with me. I am trying to modify the given array using a foreach loop that runs through each array key/value recursively. However, I do not want to replace a key or value, instead I need to add a new key and value to the same level as the matched key.
In the code below I walk through each key value in the array, and if a key and value match, I want to add a new key to that same level where the match occurred. I can find the match, but I don't know how to update the array. I would rather update the existing array than build a new one.
Here's what I am trying to accomplish
Given this array:
array(
array(
'name' => 'name',
'label' => 'Label'
),
array(
'name' => 'name',
'label' => 'Label',
'sub_fields' => array(
array(
'name' => 'my_desired_target',
'label' => 'Label'
)
)
)
);
function change_recursively($arr){
foreach($arr as $key => $val){
if(is_array($val)){
change_recursively($val);
}else{
if($key == 'name' && $val == 'my_desired_target'){
//How to add new key here?
$arr['new_key'] = 'my new value';
}
}
}
}
Below is the result I am looking for if I were to var_dump $arr. In this case the key 'name' and the value 'my_desired_target" were matched, and a new key 'new_key' and value 'my new value' were added to that same level.
array(
array(
'name' => 'name',
'label' => 'Label'
),
array(
'name' => 'name',
'label' => 'Label',
'sub_fields' => array(
array(
'name' => 'my_desired_target',
'label' => 'Label',
'new_key' => 'my new value'
)
)
)
)
I have looked into using array_walk_recursive, and array_map, but neither function seems to track how deep you are in the array.
Use references:
Helpful link: PHP foreach change original array values
Your working code:
$arr = array(
array(
'name' => 'name',
'label' => 'Label'
),
array(
'name' => 'name',
'label' => 'Label',
'sub_fields' => array(
array(
'name' => 'my_desired_target',
'label' => 'Label'
)
)
)
);
function change_recursively(&$arr){
foreach($arr as $key => &$val){
if(is_array($val)){
change_recursively($val);
}else{
if($key == 'name' && $val == 'my_desired_target'){
//How to add new key here?
$arr['new_key'] = 'my new value';
}
}
}
}
change_recursively($arr);
print_r($arr);
Hope it helps!

Using array_search for multi value search

$array_subjected_to_search =array(
array(
'name' => 'flash',
'type' => 'hero'
),
array(
'name' => 'zoom',
'type' => 'villian'
),
array(
'name' => 'snart',
'type' => 'antihero'
),
array(
'name' => 'flash',
'type' => 'camera'
)
);
$key = array_search('flash', array_column($array_subjected_to_search, 'name'));
var_dump($array_subjected_to_search[$key]);
This works fine, but is there a way to search using multiple values: eg. get key where name='flash' && type='camera' ?
is there a way to search using multiple values: eg. get key where
name='flash' && type='camera' ?
Simply with array_keys function:
$result_key = array_keys($array_subjected_to_search, [ 'type' => 'camera','name' => 'flash']);
print_r($result_key);
The output:
Array
(
[0] => 3
)
The array_search function accepts an array as parameters the following will work for the use case you provided.
$array_subjected_to_search =array(
array(
'name' => 'flash',
'type' => 'hero'
),
array(
'name' => 'zoom',
'type' => 'villian'
),
array(
'name' => 'snart',
'type' => 'antihero'
),
array(
'name' => 'flash',
'type' => 'camera'
)
);
$compare = array(
'name'=>'flash',
'type'=>'camera'
);
$key = array_search($compare, $haystack);
var_dump($haystack[$key]);
Note: your current search will not function correctly it will always return the zero index because the array_search returns 0 or false.
$key = array_search('flash', array_column($array_subjected_to_search, 'name'));
var_dump($array_subjected_to_search[$key]);
I think I would just make my own function using a loop that will just retrieve the array I want based on either one or two parameters.
function getValueMatch($array, $val1, $val2 = false, $type = 'name')
{
foreach($array as $key => $row) {
# See note below, but it might be handy to have a reversible key name
if($row[$type] == $val1) {
if($val2) {
# You can put a changeable key name to reverse-find
# It might be helpful to search for the other key first
# at some point, best to keep your options open!
$altVar = ($type == 'name')? 'type' : 'name';
if($row[$altVar] == $val2)
return $row;
}
else
return $row;
}
}
}
$array =array(
array(
'name' => 'flash',
'type' => 'hero'
),
array(
'name' => 'zoom',
'type' => 'villian'
),
array(
'name' => 'snart',
'type' => 'antihero'
),
array(
'name' => 'flash',
'type' => 'camera'
)
);
print_r(getValueMatch($array,'flash','camera'));
Gives you:
Array
(
[name] => flash
[type] => camera
)
Example of reverse match (type instead of name):
print_r(getValueMatch($array,'antihero',false,'type'));
Gives you:
Array
(
[name] => snart
[type] => antihero
)

Categories