I have an array on variable $menu:
array (size=3)
0 =>
array (size=2)
'principal' => string 'regulacao' (length=9)
'submenu' => string 'agenda' (length=6)
1 =>
array (size=2)
'principal' => string 'regulacao' (length=9)
'submenu' => string 'marcacao' (length=8)
2 =>
array (size=2)
'principal' => string 'gestao' (length=6)
'submenu' => string 'usuarios' (length=8)
I need to know if an word exists, ex:
if (array_value_exists('regulacao')) //return true
if (array_value_exists('marcacao')) //return true
if (array_value_exists('usuarios')) //return true
if (array_value_exists('gestao')) //return true
I trying using if (array_search('regulacao', $menu)) but it's not works
Any idea?
I believe this code solves your problem:
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 true;
}
}
return false;
}
Array_search not works with nested array.
To do this search you need to iterate your $menu array and call array_search on each sub array. Like this:
$word = "regulacao";
foreach($menu as $arr) {
$arrKey = array_search($word, $arr);
if($arrKey){
print "Found {$word} in key {$arrKey}";
// break; <-- uncomment this line for search only one occurrence
}
}
Related
I am trying to create and array to fill for my form_dropdown() for my view:
<?php echo form_dropdown('vendor', $vendors, '', 'class="form-control"') ?>
However, I am only getting the last value based on the function that generates the array:
public function get_vendors() {
$vendors = $this->db->table('vendor')->get()->getResultArray();
// Return key => value pair array
$array = array(
0 => 'Not Assigned'
);
if (!empty($vendors)) {
foreach ($vendors as $vendor) {
$array = array(
$vendor['id'] => $vendor['vendor']
);
}
}
return $array;
}
This function is within my model. The only problem I have is that it's returning only the last row from the table. However when I do a var_dump() for the $vendors I get all the rows. Not sure what I am doing wrong.
array (size=2)
0 =>
array (size=4)
'id' => string '1' (length=1)
'vendor' => string 'Blue Chip' (length=9)
'datecreated' => string '2022-08-16' (length=10)
'datemodified' => string '2022-08-16' (length=10)
1 =>
array (size=4)
'id' => string '2' (length=1)
'vendor' => string 'ASP' (length=3)
'datecreated' => string '2022-08-30' (length=10)
'datemodified' => string '2022-08-31' (length=10)
Changing the query to from getResultArray() to getResultObject() did the trick. So I was able to use $array[$vendor->id] = $vendor->vendor;
public function get_vendors() {
$vendors = $this->db->table('vendor')->get()->getResultObject();
// Return key => value pair array
$array = array(
0 => 'Not Assigned'
);
if (!empty($vendors)) {
foreach ($vendors as $vendor) {
$array[$vendor->id] = $vendor->vendor;
}
}
return $array;
}
If you still want to use getResultArray():
public function get_vendors() {
$vendors = $this->db->table('vendor')->get()->getResultArray();
// Return key => value pair array
$array = array(
0 => 'Not Assigned'
);
if (!empty($vendors)) {
foreach ($vendors as $vendor) {
$array[$vendor['id']] => $vendor['vendor'];
}
}
return $array;
}
Over the past few days, I've been thinking about how to deal with iterating over keys in a multidimensional array, and I just cannot figure it out. The problem is, I don't know how deep the array might be - I want my code to be able to handle arrays of any depth.
The array itself comes from Advanced Custom Fields, but that's not too important. I need to iterate over the array, run a function on every array key which starts with field_ (to convert it from field_* to its proper name like post_title or something), and reconstruct the array with the same structure and values (although the order is not important). The array looks like this:
array (size=12)
'field_5b23d04fef8a6' => string '' (length=0)
'field_5b23d04fefa99' => string '' (length=0)
'field_5b23d04fefe85' => string '' (length=0)
'field_5b23d04ff0077' => string '' (length=0)
'field_5b23d04ff026c' => string '' (length=0)
'field_5b23d0bdb3c1a' => string 'Version 1' (length=9)
'field_5b23d0f48538b' => string '' (length=0)
'field_5b23d0f485772' => string '' (length=0)
'field_5b23d0d52be2d' => string '' (length=0)
'field_5b5ed10a6a7bc' => string '' (length=0)
'field_5b5ed10a6bcf5' =>
array (size=1)
0 =>
array (size=1)
'field_5b5ed10acd264' =>
array (size=1)
0 =>
array (size=6)
'field_5b5ed10b0c9ca' => string '0' (length=1)
'field_5b5ed10b0cce2' => string 'TEST1234' (length=8)
'field_5b5ed10b0d0fd' => string 'Download title' (length=14)
'field_5b5ed10b0d4e2' => string 'EN' (length=2)
'field_5b5ed10b0d72e' => string 'A00' (length=3)
'field_5b5ed10b0df27' => string '887' (length=3)
'field_5b23d088500a4' => string '' (length=0)
What would be the best way to handle this? I've looked at recursive functions and ResursiveArrayIterator already, but none of the examples I found were close enough to let me figure out what I need.
You can recursively call the same function if it finds a nested array like this:
$input = array(
'field_5b23d04fef8a6' => '',
'field_5b23d04fefa99' => '',
'field_5b23d04fefe85' => '',
'field_5b23d04ff0077' => '',
'field_5b23d04ff026c' => '',
'field_5b23d0bdb3c1a' => 'Version 1',
'field_5b23d0f48538b' => '',
'field_5b23d0f485772' => '',
'field_5b23d0d52be2d' => '',
'field_5b5ed10a6a7bc' => '',
'field_5b5ed10a6bcf5' => array(
array(
'field_5b5ed10acd264' => array(
array(
'field_5b5ed10b0c9ca' => '0',
'field_5b5ed10b0cce2' => 'TEST1234',
'field_5b5ed10b0d0fd' => 'Download title',
'field_5b5ed10b0d4e2' => 'EN',
'field_5b5ed10b0d72e' => 'A00',
'field_5b5ed10b0df27' => '887',
),
),
),
),
'field_5b23d088500a4' => '',
);
// recursively re-key array
function dostuff($input){
// always refer to self, even if you rename the function
$thisfunction = __function__;
$output = array();
foreach($input as $key => $value){
// change key
$newkey = (is_string($key) ? preg_replace('/^field_/', 'post_title_', $key) : $key);
// iterate on arrays
if(is_array($value)){
$value = $thisfunction($value);
}
$output[$newkey] = $value;
}
return $output;
}
var_dump(dostuff($input));
So I was looking at this and to my knowledge there is no wrapper function for recursion with callbacks, so here it is:
// general function for recursively doing something
// $input -> array() / the array you wan to process
// $valuefunction -> callable | null / function to run on all values *
// $keyfunction -> callable | null / function to run on all keys *
// * at least one has to defined or there is nothing to do
// callable has two inputs
// $input -> current branch
// $depth -> (int) how deep in the structure are we
// i.e: recursion($some_array, function($branch, $depth){something..}, 'trim');
function recursion($input, $valuefunction = false, $keyfunction = false){
if(!is_array($input)){
trigger_error('Input is '.gettype($input).'. Array expected', E_USER_ERROR);
return null;
}
if(!is_callable($valuefunction)){$valuefunction = false;}
if(!is_callable($keyfunction)){$keyfunction = false;}
if(!$valuefunction && !$keyfunction){
trigger_error('Input is unchanged!', E_USER_WARNING);
return $input;
}
// use recursion internally, so I can pass stuff by reference
// and do the above checks only once.
$recurse = function(&$branch, $depth = 0) use (&$recurse, &$valuefunction, &$keyfunction){
$output = array();
foreach($branch as $key => $value){
$key = $keyfunction ? $keyfunction($key, $depth) : $key;
$output[$key] = (is_array($value) ?
$recurse($value, $depth + 1) :
($valuefunction ?
$valuefunction($value, $depth) :
$value
)
);
}
return $output;
};
return $recurse($input);
}
$valuefunction = function($value, $depth){
return is_string($value) ? $depth.'_'.$value : $value;
};
function keyfunction($key){
return is_string($key) ? preg_replace('/^field_/', 'post_title_', $key) : $key;
}
var_dump(recursion($input, $valuefunction, 'keyfunction'));
Or for your example:
var_dump(recursion($input, 0, function($key){
return is_string($key) ? preg_replace('/^field_/', 'post_title_', $key) : $key;
}));
You could do something like this:
$arr = [
'a',
'b',
'c',
[
'd',
'e',
'f',
[
'g',
'h',
'i',
],
],
];
class MyIterator
{
public function iterate( $array )
{
foreach ( $array as $a ) {
if ( is_array( $a ) ) {
$this->iterate($a);
} else {
echo $a;
}
}
}
}
$iterator = new MyIterator();
$iterator->iterate($arr);
It prints this:
abcdefghi
You can iterate over array recursively like this
function recursiveWalk($array, callable $x)
{
$result = [];
foreach ($array as $key => $value) {
if (is_array($value)) {
$result[$key] = recursiveWalk($value, $x);
} else {
$result[$key] = $x($value);
}
}
return $result;
}
Here example:
$array = [
"aaa" => 1,
"sub1" => [
"xxx" => 2,
"sub2" => [
"yyy" => 3,
"ttt" => 4
]
]
];
print_r(recursiveWalk($array, function ($x) {
return $x + 1;
}));
Array
(
[aaa] => 2
[sub1] => Array
(
[xxx] => 3
[sub2] => Array
(
[yyy] => 4
[ttt] => 5
)
)
)
I am trying to migrate user data from a Drupal database to Wordpress. I'm trying to parse through a data column from Drupal and reorganize it so I can import it where I need to in the Wordpress database. The data column in Drupal is a serialized string:
a:12:{s:23:"profile_membership_type";s:4:"Full";s:21:"ms_membership_add_new";s:0:"";s:18:"ms_membership_mpid";s:0:"";s:25:"ms_membership_amount_paid";s:0:"";s:32:"ms_membership_transaction_number";s:0:"";s:30:"ms_membership_current_payments";i:1;s:26:"ms_membership_max_payments";s:0:"";s:24:"ms_membership_start_date";a:3:{s:4:"year";s:4:"2014";s:5:"month";s:1:"2";s:3:"day";s:2:"13";}s:27:"ms_membership_should_expire";b:0;s:24:"ms_membership_expiration";a:3:{s:4:"year";s:4:"2014";s:5:"month";s:1:"2";s:3:"day";s:2:"13";}s:20:"ms_membership_status";i:3;s:7:"contact";i:1;}
I keep getting this error:
Warning: Invalid argument supplied for foreach()
This is my code thus far:
$fixed = preg_replace_callback(
'/s:([0-9]+):\"(.*?)\";/',
function ($matches) { return "s:".strlen($matches[2]).':"'.$matches[2].'";'; },
$data
);
$original_array = unserialize($fixed);
foreach ($original_array as $key => $value) {
echo $value['profile_membership_type'];
};
check with if condition before iteration
if(is_array($original_array) && !empty($original_array)){
foreach ($original_array as $key => $value) {
echo $value['profile_membership_type'];
}
}
Just cast to an array.
foreach ( (array) $original_array as $key => $value) {
echo $value['profile_membership_type'];
}
You can easily check to see if the variable you're iterating through is an array;
if(isset($original_array) && is_array($original_array)) {
foreach ( $original_array as $key => $value) {
echo $value['profile_membership_type'];
}
}
Edited to include a check to ensure the variable exists.
You have a php serialized string.
I presume the leading f in your question is a typo, as the rest is a valid serialized array:
$array = unserialize('a:12:{s:23:"profile_membership_type";s:4:"Full";s:21:"ms_membership_add_new";s:0:"";s:18:"ms_membership_mpid";s:0:"";s:25:"ms_membership_amount_paid";s:0:"";s:32:"ms_membership_transaction_number";s:0:"";s:30:"ms_membership_current_payments";i:1;s:26:"ms_membership_max_payments";s:0:"";s:24:"ms_membership_start_date";a:3:{s:4:"year";s:4:"2014";s:5:"month";s:1:"2";s:3:"day";s:2:"13";}s:27:"ms_membership_should_expire";b:0;s:24:"ms_membership_expiration";a:3:{s:4:"year";s:4:"2014";s:5:"month";s:1:"2";s:3:"day";s:2:"13";}s:20:"ms_membership_status";i:3;s:7:"contact";i:1;}');
var_dump($array);
/*
array (size=12)
'profile_membership_type' => string 'Full' (length=4)
'ms_membership_add_new' => string '' (length=0)
'ms_membership_mpid' => string '' (length=0)
'ms_membership_amount_paid' => string '' (length=0)
'ms_membership_transaction_number' => string '' (length=0)
'ms_membership_current_payments' => int 1
'ms_membership_max_payments' => string '' (length=0)
'ms_membership_start_date' =>
array (size=3)
'year' => string '2014' (length=4)
'month' => string '2' (length=1)
'day' => string '13' (length=2)
'ms_membership_should_expire' => boolean false
'ms_membership_expiration' =>
array (size=3)
'year' => string '2014' (length=4)
'month' => string '2' (length=1)
'day' => string '13' (length=2)
'ms_membership_status' => int 3
'contact' => int 1
*/
Note that there is only a single profile_membership_type element, so there is no need to loop:
echo $array['profile_membership_type']; // Full
Hello i am trying to combine two php array.
First one
array (size=13)
0 =>
object(stdClass)[30]
public 'ID' => string '1' (length=1)
public 'name' => string 'html5' (length=5)
public 'img' => string 'HTML5.png' (length=9)
1 =>
object(stdClass)[31]
public 'ID' => string '2' (length=1)
public 'name' => string 'css3' (length=4)
public 'img' => string 'css.png' (length=7)
2 =>
object(stdClass)[32]
public 'ID' => string '3' (length=1)
public 'name' => string 'php' (length=3)
public 'img' => string 'php1.png' (length=8)
3 =>
object(stdClass)[33]
public 'ID' => string '4' (length=1)
public 'name' => string 'java script' (length=11)
public 'img' => string 'javascript.png' (length=14)
Second one
array (size=3)
0 =>
object(stdClass)[26]
public 'ID' => string '1' (length=1)
public 'IDuser' => string '1' (length=1)
public 'IDskill' => string '1' (length=1)
1 =>
object(stdClass)[27]
public 'ID' => string '2' (length=1)
public 'IDuser' => string '1' (length=1)
public 'IDskill' => string '3' (length=1)
2 =>
object(stdClass)[28]
public 'ID' => string '3' (length=1)
public 'IDuser' => string '1' (length=1)
public 'IDskill' => string '4' (length=1)
ID from first array is equal to IDskill from second array. I am trying to combine to create new array if IDskill and ID are same, with something like this in new array
public 'ID' => string '1' (length=1)
public 'name' => string 'html5' (length=5)
public 'img' => string 'HTML5.png' (length=9)
===>New field public 'MATCH' => string '1' (length=9)
use array_merge() function
<?php
$a1=array("red","green");
$a2=array("blue","yellow");
print_r(array_merge($a1,$a2));
?>
or
<?php
$fname=array("Peter","Ben","Joe");
$age=array("35","37","43");
$c=array_combine($fname,$age);
print_r($c);
?>
Try this ( where a1 is first array and a2 is second one and $result is final, merged array ):
$result = array();
$n=0;
foreach($a1 as $k=>$v) {
if (isset($v->ID) && isset($a2[$n]->ID) && $v->ID==$a2[$n]->ID) {
$result[$n]=$v;
$result[$n]->MATCH=1;
}
$n++;
}
print_r($result);
You could use array_map and anonymous functions:
<?php
$first_array = array(...);
$second_array = array(...);
// Anonymous function to extract the IDskills from the second array:
$get_IDs = function($element) {
return($element->IDskill);
};
// Array of (just) IDskills of the second array:
$IDs = array_map($get_IDs, array_filter($second_array, function($element) {
// Anonymous function to filter $second_array elements without IDskill:
return(isset($element->IDskill));
}));
// Another anonymous function that returns a new array with elements from
// $first_array with the new MATCH property.
// use(&$IDs) makes $IDs available inside the function scope:
$check_match = function($element) use(&$IDs) {
// We use clone because we don't want to modify the original array values:
$match_element = clone $element;
if(isset($match_element->ID))
$match_element->MATCH = in_array($match_element->ID, $IDs);
else
$match_element->MATCH = false;
return($match_element);
};
$match = array_map($check_match, $first_array);
?>
If you don't want to use the two first anonymous functions or don't want to create the $IDs array you can replace use(&$IDs) for use(&$second_array) and the line:
$match_element->MATCH = in_array($match_element->ID, $IDs);
for a loop that iterates through $second_array elements to check whether any of them has an IDskill equal to $match_element->ID.
Moreover, you may not need to check if IDskill and ID exist if all the elements in the arrays have the same properties.
let me add my two cents, how to find element matching ID from the 1st array in the second one
$tmp = array_filter($array2, function($ar2) use ($ID) { return $ar2->IDskill === $ID; });
if ($tmp) // Found
else // Not found
all code may be
result = array()
foreach ($array1 as $item) {
$ID = $item->ID;
$tmp = array_filter($array2, function($ar2) use ($ID) { return $ar2->IDskill === $ID; });
if ($tmp) { // Found
$tmp = $item;
$tmp->MATCH = 1;
result[] = $tmp;
}
}
I am trying to remove pieces of a multidimensional array if a certain condition is met. The array can be as shown below, call it $friends:
array (size=3)
0 =>
array (size=1)
0 =>
object(stdClass)[500]
public 'id' => int 2
public 'first_name' => string 'Mary' (length=4)
public 'last_name' => string 'Sweet' (length=5)
1 =>
array (size=1)
0 =>
object(stdClass)[501]
public 'id' => int 9
public 'first_name' => string 'Joe' (length=3)
public 'last_name' => string 'Bob' (length=3)
2 =>
array (size=1)
0 =>
object(stdClass)[502]
public 'id' => int 1
public 'first_name' => string 'Shag' (length=4)
public 'last_name' => string 'Well' (length=4)
I have a function called is_followed, that let's me see if the id of one of the people in the array is being followed by the "user". The code I am trying is:
//remove followed friends from the $friends array
$i=0;
foreach($friends as $friend) {
foreach($friend as $f) {
if(Fanfollow::is_followed($id,$f->id)) {
unset($friend[$i]);
}
}
$i++;
}
The $id is the id of the current user.
However, this is not working. I know that using unset on $friend and not $friends is probably the issue. But using unset on $friends also won't work, because it is the higher level array. Any ideas? Thank you.
If you're trying to take down the first parent keys, use the first foreach keys instead:
foreach($friends as $i => $friend) {
// ^ assign a key
foreach($friend as $f) {
if(Fanfollow::is_followed($id,$f->id)) {
unset($friends[$i]);
// unset this
}
}
}
Or if only for that single friend:
foreach($friends as $friend) {
foreach($friend as $i => $f) {
// ^ this key
if(Fanfollow::is_followed($id,$f->id)) {
unset($friend[$i]);
// unset this
}
}
}
array_filter comes to the rescue:
array_filter($friend,
function($f) use($id) { return Fanfollow::is_followed($id,$f->id)); }
);
Though the solution with foreach is legit, array_filteris much more clear and sematically correct.