I have an GLOBAL array that keeps all the configurations, it looks like this:
$_SOME_ARRAY = array(
'some_setting' => array(
'some_value' => '1',
'other' => 'value'
),
'something_else' => 1,
);
How can I delete keys from this array, using some function like:
deleteFromArray('some_setting/other')
I have tried different things, but can't seem to find a way, to delete it without manually calling unset($_SOME_ARRAY['some_setting']['other'])
EDIT
I have tried working on with it. The only solution I see so far, is by "rebuilding" the original array, by looping through each value and verify. The progress:
public static function delete($path) {
global $_EDU_SETUP;
$exploded_path = explode('/', $path);
$newConfig = array();
$delete = false;
foreach($exploded_path as $bit) {
if(!$delete) {
$loop = $_EDU_SETUP;
} else {
$loop = $delete;
}
foreach($loop as $key => $value) {
if($key == $bit) {
echo 'found first: ' . $key . '<br />'; // debugging
if(!$delete) {
$delete = $_EDU_SETUP[$key];
} else {
$delete = $delete[$key];
}
} else {
$newConfig[$key] = $value;
}
}
}
$_EDU_SETUP = $newConfig;
}
The array could look like this:
$array = array(
'a' => array(
'a',
'b',
'c'
),
'b' => array(
'a',
'b',
'c' => array(
'a',
'b',
'c' => array(
'a'
),
),
)
);
And to delete $array['b']['c'] you would write Config::delete('b/c'); - BUT: It deletes whole B. It is only supposed to delete C.
Any ideas?
This what you can do, assuming the array has 2 levels of data.
$_SOME_ARRAY = array(
'some_setting' => array(
'some_value' => '1',
'other' => 'value'
),
'something_else' => 1,
);
function deleteFromArray($param){
global $_SOME_ARRAY ;
$param_values = explode("/",$param);
if(count($param_values) == 2 ){
unset($_SOME_ARRAY[$param_values[0]][$param_values[1]]);
}else{
unset($_SOME_ARRAY[$param_values[0]]);
}
}
deleteFromArray('some_setting/other');
print_r($_SOME_ARRAY);
You can modify the function to add more strict rules by checking if the key exists before doing unset using the function array_key_exists()
how do you like this ?
$_SESSION = $_SOME_ARRAY; // Btw it should be session from beginning...
function deleteFromArray($string)
{
$array = explode("/",$sting);
foreach($array as $arrA)
{
foreach($array as $arrB)
{
unset($_SESSION[$arrA][$arrB]);
}
}
}
now you could delete more than one entry like
deleteFromArray('some_setting/some_value/a_other_value')
but take care of using dim1array names in dim2array...
of corse you could add more foreach or make a recursiv function out of it to get deep in the array
do you want to delete particular array using a unique index(like a primary id)?, i would use a for loop to look for that particular index then delete that array...E.g delete array where the index = 1 , pls check above
foreach ($_SOME_ARRAY as $a => $key)//get all child arrays of '$_SOME_ARRAY '
{
foreach($Key as $b => $key2)//get values of the child arrays
{
if($Key[0] == 1)// if the index at[0] equals 1
{
unset($arr[$a][$b]); //delete that array
}
}
}
Related
I need to find the last found element of a specific value from an array. I giving an example in php of what I'm actually seeking for.
$Data = array(
'0' => 'car',
'1' => 'bike',
'2' => 'bus',
'3' => 'bike',
'4' => 'boat'
);
$key = array_search('bike', $Data) // it returns $key = 1 as result which the first element matched inside the array.
I want $key = 3 which is the last matched element.
Any suggestion appreciated.
PHP code demo
<?php
ini_set("display_errors", 1);
$Data = array(
'0' => 'car',
'1' => 'bike',
'2' => 'bus',
'3' => 'bike',
'4' => 'boat'
);
$toSearch="bike";
$index=null;
while($key=array_search($toSearch, $Data))
{
$index=$key;
unset($Data[$key]);
}
echo $index;
Here is the more simple and highly performace way. For it only calculate once, you can access it many time. The live demo.
$data = array_flip($Data);
echo $data['bike'];
after the flip, only keep the last element of the same elements. Here is the print_r($data)
Array
(
[car] => 0
[bike] => 3
[bus] => 2
[boat] => 4
)
We can use array_reverse to reverse array.
$key = array_search('bike', array_reverse($Data,true));
It will return 3.
you can use krsort to sort the array by key.
krsort($Data);
$key = array_search('bike', $Data);
echo $key;
Working example: https://3v4l.org/fYOgN
For this I am created one function it is very easy to use. You can pass only array and parameters.
function text_to_id($value, $arr_master) {
$id_selected = 0;
$search_array = $arr_master;
if (in_array($value, $search_array)) {
$id_selected = array_search($value, $search_array);
// pr($id_selected);exit;
}
if (!$id_selected) {
foreach ($search_array as $f_key => $f_value) {
if (is_array($f_value)) {
if (in_array($value, $f_value)) {
$id_selected = $f_key;
break;
}
} else if ($value == $f_value) {
$id_selected = $f_key;
break;
}
else;
}
}
return $id_selected;
}
this function use like this
$variable = text_to_id('bike', $your_array);
I have an array like:
$array = array(
'name' => 'Humphrey',
'email' => 'humphrey#wilkins.com
);
This is retrieved through a function that gets from the database. If there is more than one result retrieved, it looks like:
$array = array(
[0] => array(
'name' => 'Humphrey1',
'email' => 'humphrey1#wilkins.com'
),
[1] => array(
'name' => 'Humphrey2',
'email' => 'humphrey2#wilkins.com'
)
);
If the second is returned, I can do a simple foreach($array as $key => $person), but if there is only one result returned (the first example), I can't run a foreach on this as I need to access like: $person['name'] within the foreach loop.
Is there any way to make the one result believe its a multidimensional array?
Try this :
if(!is_array($array[0])) {
$new_array[] = $array;
$array = $new_array;
}
I would highly recommended making your data's structure the same regardless of how many elements are returned. It will help log terms and this will have to be done anywhere that function is called which seems like a waste.
You can check if a key exists and do some logic based on that condition.
if(array_key_exists("name", $array){
//There is one result
$array['name']; //...
} else {
//More then one
foreach($array as $k => $v){
//Do logic
}
}
You will have the keys in the first instance in the second yours keys would be the index.
Based on this, try:
function isAssoc(array $arr)
{
if (array() === $arr) return false;
return array_keys($arr) !== range(0, count($arr) - 1);
}
if(isAssoc($array)){
$array[] = $array;
}
First check if the array key 'name' exists in the given array.
If it does, then it isn't a multi-dimensional array.
Here's how you can make it multi-dimensional:
if(array_key_exists("name",$array))
{
$array = array($array);
}
Now you can loop through the array assuming it's a multidimensional array.
foreach($array as $key => $person)
{
$name = $person['name'];
echo $name;
}
The reason of this is probably because you use either fetch() or fetchAll() on your db. Anyway there are solutions that uses some tricks like:
$arr = !is_array($arr[0]) ? $arr : $arr[0];
or
is_array($arr[0]) && ($arr = $arr[0]);
but there is other option with array_walk_recursive()
$array = array(
array(
'name' => 'Humphrey1',
'email' => 'humphrey1#wilkins.com'
),
array(
'name' => 'Humphrey2',
'email' => 'humphrey2#wilkins.com'
)
);
$array2 = array(
'name' => 'Humphrey2',
'email' => 'humphrey2#wilkins.com'
);
$print = function ($item, $key) {
echo $key . $item .'<br>';
};
array_walk_recursive($array, $print);
array_walk_recursive($array2, $print);
I`ve got the following array:
$myarray = array(
2 => array(
'id' => '2',
'parent_id' => '1',
),
4 => array(
'id' => '4',
'parent_id' => '2',
),
3 => array(
'id' => '3',
'parent_id' => '1',
),
1 => array(
'id' => '1',
'parent_id' => '0',
)
);
and the goal is to have the following output:
1
1.2
1.2.4
1.3
The problem is that I need to do that without recursion. Here is some kind of an answer but the guys there are building tree while I need to have strings. I tried to use some kind of $basestring variable in order to know where am I, but still it did not work without recursion. Any ideas how to do that?
Thank you
UPD My first attempt was the following:
foreach($myarray as $k=>$value){
if($value['parent_id'] == 0){
$string = '1';
$id = $value['id'];
$newarr[0] = $string;
$basestring = $string.'.';
}elseif($value['parent_id'] == 1){
$string = $basestring.$value['id'];
$id = $value['id'];
$newarr[$id] = $string;
}elseif($value['one'] == 2){
$string = $basestring.$value['parent_id'].'.'.$value['id'];
$id = $value['id'];
$newarr[$id] = $string;
}elseif($value['parent_id'] == 3){
$string = $basestring.$value['parent_id'].'.'.$value['id'];
$id = $value['id'];
$newarr[$id] = $string;
}elseif($value['parent_id'] == 4){
$string = $basestring.$value['parent_id'].'.'.$value['id'];
$id = $value['id'];
$newarr[$id] = $string;
}//etc...
}
}
but obviously it failed due to non-scalability. I need to code somehow the iteration from child to parent here
An iterative solution could work something like this:
foreach ($myarray as $x) {
$temp = $x;
$string = [];
while (true) {
$string[] = $temp['id']; // add current level id
if (!isset($myarray[$temp['parent_id']])) break; // break if no more parents
$temp = $myarray[$temp['parent_id']]; // replace temp with parent
}
$strings[] = implode('.', array_reverse($string));
// array_reverse is needed because you've added the levels from bottom to top
}
Basically for each element of the array, create a temporary copy, then find its parents by key and set the temporary copy to the parent until no more parents are found. Add the ids into an array as you go and build the string from the array when you get to the end.
This assumes your array is valid, in that it does not contain circular references (e.g. one level being its own ancestor). To prevent an infinite loop if this did happen, you could increment a variable within the while loop and break if it reached some reasonable limit.
Might be a newbie question but I've been trying to figure this problem and it's doing my head in.
I have the following array :
[0] => Array
(
[provisionalBookingRoomID] => 1
[totalSpecificRoomCount] => 2
)
[1] => Array
(
[provisionalBookingRoomID] => 2
[totalSpecificRoomCount] => 5
)
I need a php function that searches through the array for the value of 'provisionalBookingRoomID' and returns the value of 'totalSpecificRoomCount'
basically something like the following
getProvisionalTotalRoomsCount($currentRoom, $arrayOfRooms);
// getProvisionalTotalRoomsCount('1', $arrayOfRooms) should return 2;
Any ideas?
Check this:
getProvisionalTotalRoomsCount($currentRoom, $arrayOfRooms){
foreach($arrayOfRooms as $key=>$value){
if($value['provisionalBookingRoomID'] == $currentRoom){
return $value['totalSpecificRoomCount'];
}
}
}
For anyone looking for a generic function :
function findValueInArray($array, $searchValue, $searchKey, $requiredKeyValue) {
foreach($array as $key=>$value){
if($value[$searchKey] == $searchValue){
return $value[$requiredKeyValue];
}
}
}
// Usage : findValueInArray($provisionalBookedRoomsArray, '1', 'provisionalBookingRoomID', 'totalSpecificRoomCount');
If you are likely to work with more than one value, you could build a new array with a 1->1 map for those attributes.
<?php
$items = array(
array(
'name' => 'Foo',
'age' => 23
),
array(
'name' => 'Bar',
'age' => 47
)
);
// Php 7
$name_ages = array_column($items, 'name', 'age');
echo $name_ages['Foo']; // Output 23
// Earlier versions:
$name_ages = array();
foreach($items as $value)
{
$name_ages[$value['name']] = $value['age'];
}
echo $name_ages['Foo']; // Output 23
$value = 0;
$array = array(array("provisionalBookingRoomID"=>1,"totalSpecificRoomCount"=>2),array("provisionalBookingRoomID"=>2,"totalSpecificRoomCount"=>5));
array_map(
function($arr) use (&$value) {
if($arr['provisionalBookingRoomID']==1) {
$value = $arr['totalSpecificRoomCount'];
}
},$array
);
echo $value;
I have a deep and long array (matrix). I only know the product ID.
How found way to product?
Sample an array of (but as I said, it can be very long and deep):
Array(
[apple] => Array(
[new] => Array(
[0] => Array([id] => 1)
[1] => Array([id] => 2))
[old] => Array(
[0] => Array([id] => 3)
[1] => Array([id] => 4))
)
)
I have id: 3, and i wish get this:
apple, old, 0
Thanks
You can use this baby:
function getById($id,$array,&$keys){
foreach($array as $key => $value){
if(is_array( $value )){
$result = getById($id,$value,$keys);
if($result == true){
$keys[] = $key;
return true;
}
}
else if($key == 'id' && $value == $id){
$keys[] = $key; // Optional, adds id to the result array
return true;
}
}
return false;
}
// USAGE:
$result_array = array();
getById( 3, $products, $result_array);
// RESULT (= $result_array)
Array
(
[0] => id
[1] => 0
[2] => old
[3] => apple
)
The function itself will return true on success and false on error, the data you want to have will be stored in the 3rd parameter.
You can use array_reverse(), link, to reverse the order and array_pop(), link, to remove the last item ('id')
Recursion is the answer for this type of problem. Though, if we can make certain assumptions about the structure of the array (i.e., 'id' always be a leaf node with no children) there's further optimizations possible:
<?php
$a = array(
'apple'=> array(
'new'=> array(array('id' => 1), array('id' => 2), array('id' => 5)),
'old'=> array(array('id' => 3), array('id' => 4, 'keyname' => 'keyvalue'))
),
);
// When true the complete path has been found.
$complete = false;
function get_path($a, $key, $value, &$path = null) {
global $complete;
// Initialize path array for first call
if (is_null($path)) $path = array();
foreach ($a as $k => $v) {
// Build current path being tested
array_push($path, $k);
// Check for key / value match
if ($k == $key && $v == $value) {
// Complete path found!
$complete= true;
// Remove last path
array_pop($path);
break;
} else if (is_array($v)) {
// **RECURSION** Step down into the next array
get_path($v, $key, $value, $path);
}
// When the complete path is found no need to continue loop iteration
if ($complete) break;
// Teardown current test path
array_pop($path);
}
return $path;
}
var_dump( get_path($a, 'id', 3) );
$complete = false;
var_dump( get_path($a, 'id', 2) );
$complete = false;
var_dump( get_path($a, 'id', 5) );
$complete = false;
var_dump( get_path($a, 'keyname', 'keyvalue') );
I tried this for my programming exercise.
<?php
$data = array(
'apple'=> array(
'new'=> array(array('id' => 1), array('id' => 2), array('id' => 5)),
'old'=> array(array('id' => 3), array('id' => 4))
),
);
####print_r($data);
function deepfind($data,$findfor,$depth = array() ){
foreach( $data as $key => $moredata ){
if( is_scalar($moredata) && $moredata == $findfor ){
return $depth;
} elseif( is_array($moredata) ){
$moredepth = $depth;
$moredepth[] = $key;
$isok = deepfind( $moredata, $findfor, $moredepth );
if( $isok !== false ){
return $isok;
}
}
}
return false;
}
$aaa = deepfind($data,3);
print_r($aaa);
If you create the array once and use it multiple times i would do it another way...
When building the initial array create another one
$id_to_info=array();
$id_to_info[1]=&array['apple']['new'][0];
$id_to_info[2]=&array['apple']['new'][2];