I am working on an array and I would like to get all the arrays between two values of an array eg
$fields = array(
'a' => array(
'name' => 'username',
'type' => 'text',
),
'b' => array(
'name' => 'birthday',
'type' => 'text',
),
'c' => array(
'name' => 'address',
'type' => 'text',
),
'd' => array(
'name' => 'password',
'type' => 'text',
),
);
So that given username and password I want to get the following
'b' => array(
'name' => 'birthday',
'type' => 'text',
),
'c' => array(
'name' => 'address',
'type' => 'text',
),
Simply because it comes after the array with the value of username and before the array with value of password
Thanks
Simply loop with two condition like below
$start = "username";
$end = "password";
$new = array();
$flag = false;
foreach($fields as $key=>$value){
if($value["name"] == $start){
$flag = true;
continue;
}
if($value["name"] == $end){
break;;
}
if($flag){
$new[$key] = $value;
}
}
print_r($new);
Live demo : https://eval.in/879235
function getArraysBetweenNames($name1, $name2, $array)
{
$return = [];
$foundName1 = false;
foreach ($array as $key => $item) {
if ($foundName1) {
if ($item["name"] == $name2)
break;
$return[$key] = $item;
} elseif ($item["name"] == $name1) {
$foundName1 = true;
}
}
return $return;
}
print_r(getArraysBetweenNames("username", "password", $fields));
You can extract the name values into an array, search that and slice using the search result positions:
$names = array_column($fields, 'name');
$result = array_slice($fields, $i=array_search('username', $names)+1,
array_search('password', $names)-$i);
$fields = array(
'a' => array(
'name' => 'username',
'type' => 'text',
),
'b' => array(
'name' => 'birthday',
'type' => 'text',
),
'c' => array(
'name' => 'address',
'type' => 'text',
),
'd' => array(
'name' => 'password',
'type' => 'text',
),
);
if you want b,c array from the fields you just
echo $fields[b][name];
echo $fields[b][type];
echo $fields[c][name];
echo $fields[c][type];
Related
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
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.
I have the following array. I'm not even sure if that array is properly formatted. I am not even sure if my array is right.
I want to convert the following array to a serialized XML using PHP. I am using attr tag for the attributes.
Here is the array:
$data = Array(
'name' => 'account',
'attr' => Array(
'id' => 123456
),
'children' => Array(
Array(
'name' => 'name',
'attr' => Array(),
'children' => Array(
'BBC'
),
),
Array(
'name' => 'monitors',
'attr' => Array(),
'children' => Array(
Array(
'name' => 'monitor',
'attr' => Array(
'id' => 5235632
),
'children' => Array(
Array(
'name' => 'url',
'attr' => Array(),
'children' => Array(
'http://www.bbc.co.uk/'
)
)
)
),
Array(
'name' => 'monitor',
'attr' => Array(
'id' => 5235633
),
'children' => Array(
Array(
'name' => 'url',
'attr' => Array(),
'children' => Array(
'http://www.bbc.co.uk/news'
)
)
)
)
)
)
)
);
It is quite easy with a recursive function. Your basic array contains 3 elements, the name, the attribute list and the children. So your function has to create and append a node with the name, set all attributes and iterate the child data. If the child is an scalar it is a text node, for an array call the function itself.
function appendTo($parent, $data) {
$document = $parent->ownerDocument ?: $parent;
$node = $parent->appendChild($document->createElement($data['name']));
if (isset($data['attr']) && is_array($data['attr'])) {
foreach ($data['attr'] as $name => $value) {
$node->setAttribute($name, $value);
}
}
if (isset($data['children']) && is_array($data['children'])) {
foreach ($data['children'] as $name => $childData) {
if (is_scalar($childData)) {
$node->appendChild($document->createTextNode($childData));
} elseif (is_array($childData)) {
appendTo($node, $childData);
}
}
}
}
$document = new DOMDocument();
$document->formatOutput = TRUE;
appendTo($document, $data);
echo $document->saveXml();
Output:
<?xml version="1.0"?>
<account id="123456">
<name>BBC</name>
<monitors>
<monitor id="5235632">
<url>http://www.bbc.co.uk/</url>
</monitor>
<monitor id="5235633">
<url>http://www.bbc.co.uk/news</url>
</monitor>
</monitors>
</account>
Try the following function
function assocArrayToXML($root_element_name,$ar)
{
$xml = new SimpleXMLElement("<?xml version=\"1.0\"?><{$root_element_name}></{$root_element_name}>");
$f = function($f,$c,$a) {
foreach($a as $k=>$v) {
if(is_array($v)) {
$ch=$c->addChild($k);
$f($f,$ch,$v);
} else {
$c->addChild($k,$v);
}
}
};
$f($f,$xml,$ar);
return $xml->asXML();
}
echo assocArrayToXML("root",$data);
test it here
Hope this will help.
<?php
function array2xml($arr)
{
$dom = new DomDocument('1.0');
/*
*Create Root
*/
$root = $dom->createElement($arr['name']);
if(isset($arr['attr']) && !empty($arr['attr']))
{
foreach($arr['attr'] as $key=>$val)
$root->setAttribute($key, $val);
}
$root = $dom->appendChild($root);
createChilds($arr['children'], $dom, $root);
header('Content-type: text/xml');
echo $dom->saveXML();
}
function createChilds($arr, $dom, $parent)
{
foreach($arr as $child)
{
if(isset($child['name']))
$node = $dom->createElement($child['name']);
/*
*Add Attributes
*/
if(isset($child['attr']) && !empty($child['attr']))
{
foreach($child['attr'] as $key=>$val)
$node->setAttribute($key, $val);
}
/*
*Add Childs Recursively
*/
if(isset($child['children']) && is_array($child['children']))
{
createChilds($child['children'], $dom, $node);
}
else if(isset($child) && is_string($child))
{
$text = $dom->createTextNode($child);
$parent->appendChild($text);
}
if(isset($node))
$parent->appendChild($node);
}
}
$data = Array(
'name' => 'account',
'attr' => Array(
'id' => 123456
),
'children' => Array(
Array(
'name' => 'name',
'attr' => Array(),
'children' => Array(
'BBC'
),
),
Array(
'name' => 'monitors',
'attr' => Array(),
'children' => Array(
Array(
'name' => 'monitor',
'attr' => Array(
'id' => 5235632
),
'children' => Array(
Array(
'name' => 'url',
'attr' => Array(),
'children' => Array(
'http://www.bbc.co.uk/'
)
)
)
),
Array(
'name' => 'monitor',
'attr' => Array(
'id' => 5235633
),
'children' => Array(
Array(
'name' => 'url',
'attr' => Array(),
'children' => Array(
'http://www.bbc.co.uk/news'
)
)
)
)
)
)
)
);
array2xml($data);
?>
I have two arrays with nearly the same structure.
The first array is $_POST data while the second one holds regex rules and some other stuff for data validation.
Example:
$data = array(
'name' => 'John Doe',
'address' => array(
'city' => 'Somewhere far beyond'
)
);
$structure = array(
'address' => array(
'city' => array(
'regex' => 'someregex'
)
)
);
Now I want to check
$data['address']['city'] with $structure['address']['city']['regex']
or
$data['foo']['bar']['baz']['xyz'] with $structure['foo']['bar']['baz']['xyz']['regex']
Any ideas how to achieve this with a PHP function?
Edit: It seems that I found a solution by myself.
$data = array(
'name' => 'John Doe',
'address' => array(
'city' => 'Somewhere far beyond'
),
'mail' => 'test#test.tld'
);
$structure = array(
'address' => array(
'city' => array(
'regex' => 'some_city_regex1',
)
),
'mail' => array(
'regex' => 'some_mail_regex1',
)
);
function getRegex($data, $structure)
{
$return = false;
foreach ($data as $key => $value) {
if (empty($structure[$key])) {
continue;
}
if (is_array($value) && is_array($structure[$key])) {
getRegex($value, $structure[$key]);
}
else {
if (! empty($structure[$key]['regex'])) {
echo sprintf('Key "%s" with value "%s" will be checked with regex "%s"', $key, $value, $structure[$key]['regex']) . '<br>';
}
}
}
return $return;
}
getRegex($data, $structure);
Given these arrays:
$data = array(
'name' => 'John Doe',
'address' => array(
'city' => 'Somewhere far beyond'
),
'foo' => array(
'bar' => array(
'baz' => array(
'xyz' => 'hij'
)
)
)
);
$structure = array(
'address' => array(
'city' => array(
'regex' => '[a-Z]'
)
),
'foo' => array(
'bar' => array(
'baz' => array(
'xyz' => array(
'regex' => '[0-9]+'
)
)
)
)
);
and this function:
function validate ($data, $structure, &$validated) {
if (is_array($data)) {
foreach ($data as $key => &$value) {
if (
array_key_exists($key, $structure)
and is_array($structure[$key])
) {
if (array_key_exists('regex', $structure[$key])) {
if (!preg_match($structure[$key]['regex'])) {
$validated = false;
}
}
validate($value, $structure[$key], $validated);
}
}
}
}
you can check the arrays against each other and get a validation result like so:
$validated = true;
validate($data, $structure, $validated);
if ($validated) {
echo 'everything validates!';
}
else {
echo 'validation error';
}
Ah, you've found a solution. Very nice.
I have simple questions, How to change text if id = cur_three from array below ?
$arr = array(
'id' => 'curr',
'lists' => array(
array(
'id' => 'cur_one',
'text' => 'Dollar',
),
array(
'id' => 'cur_two',
'text' => 'Euro',
),
array(
'id' => 'cur_three',
'text' => 'Peso',
),
)
);
Thank you very much...
Something simple:
foreach($arr['lists'] as $subArr) {
if ($subArr['id'] == 'cur_three') {
$subArr['text'] = 'not Peso';
}
}
Sure. Like this:
foreach($arr['lists'] as $key => $child) {
if($child['id'] == 'cur_three') {
$arr['lists'][$key]['text'] = "INR";
}
}