I need to remove a element from an associative array with an string structure.
Example:
$array = array(
"one"=>array("Hello", "world"),
"two"=>"Hi"
)
I want to create a function that removes the elements like this:
function removeElement($p) {
// With the information provided in $p something like this should happen
// unset($array["one"]["hello"])
}
removeElement("one.hello");
Your base array is associative, the inner array (key one) is not, its a indexed array, which you can not access via ["hello"] but rather [0].
You can remove the hello value by using the unset function, but the indexes will stay as they are:
$array = ['Hello', 'World']; // array(0: Hello, 1: World)
unset($array[0]); // Array is now array(1: World)
If you wish to keep unset and keep the array indexes in order, you can fetch the values using the array_values function after unset:
unset($array[0]);
$array = array_values($array); // array(0: World)
Or you could use array_splice.
When it comes to using a string as key for multidimensional array with a dot-separator I'd recommend taking a look at laravels Arr::forget method which does pretty much exactly what you are asking about.
This would be a static solution to your question, in any case, you need to use explode.
function removeElement($p, $array) {
$_p = explode('.', $p);
return unset($array[$_p[0]][$_p[1]]);
}
But bear in mind, this doesn't work if you have more in $p (like: foo.bar.quux)
Related
contains the following i am trying get array_unique value from multidimensional associative array
Here, i am only showing only sample array which is similar to this.
$array = ['games'=>[['vollyball', 'football'], ['vollyball', 'football'], ['rubby', 'chess']]];
Here is tried so for
foreach ($array as $key => &$value) {
$value = array_unique($value);
}
echo "<pre>";
print_r($array);
echo "</pre>";
exit;
Here i am expecting output is,
$array = ['games'=>[['vollyball', 'football'], ['rubby', 'chess']]];
Here the array should be same even after removing duplicate from multidimensional array.
Thanks for your time and suggestions.
you could try the following:
$a=array_values(array_unique(array_merge(...$array['games'])));
This assumes that all your usable values are below $array['games'].
Edit:
Here is another way, using array_walk:
array_walk($array['games'],function($itm){global $res; $res[json_encode($itm)]=$itm;});
echo json_encode(array_values($res));
I don't like the global $res array very much, but this is a way forward, I believe. In the callback function of array_walk() I add all values to an associative array ($res). The keys are JSON representations of their actual values. This way I will overwrite identical values in the associative array $res and will end up with a set of unique values when I apply the array_values() function at the end to turn it back into a non-associative array.
The result is:
[["vollyball","football"],["rubby","chess"]]
Here is a little demo you can check out: http://rextester.com/JEKE60636
2. edit
Using a wrapper function I can now do without the global variable $res and do the operation in-place, i. e. removing duplicate elements directly from the source array:
function unique(&$ag){
array_walk($ag,function($itm,$key) use (&$ag,&$res) {
if (isset($res[json_encode($itm)])) array_splice($ag,$key,1);
else $res[json_encode($itm)]=1.;
});
}
unique($array['games']);
echo json_encode($array)
This will result in
{"games":[["vollyball","football"],["rubby","chess"]]}
see here: http://rextester.com/YZLEK39965
I'm trying to store the users's input via the method get in an array to store it and further process it without overwriting the initial get-value. But I dont know how.. do I have to store them in a database to do that? Or can I just push every input into an array?
I believe the following should work for you... This will take all the $_GETs that you supply and put them in a new array so you can modify them without affecting the original $_GET array.
if(is_array($_GET)){
$newArr = $_GET; // modify $newArr['postFieldName'] instead of $_GET['postFieldName'] to preserve original $_GET but have new array.
}
That solution there will dupe the $_GET array. $_GET is just an internal PHP array of data, as is $_POST. You could also loop through the GETs if you do not need ALL of the GETs in your new array... You would do this by setting up an accepted array of GETs so you only pull the ones you need (this should be done anyways, as randomly accepting GETs from a form can lead to some trouble if you are also using the GETs for database/sql functions or anything permission based).
if(is_array($_GET) && count($_GET) > 0){
$array = array();
$theseOnly = array("postName", "postName2");
foreach($_GET as $key => $value){
if(!isset($array[$key]) && in_array($key, $theseOnly)){ // only add to new array if they are in our $theseOnly array.
$array[$key] = $value;
}
}
print_r($array);
} else {
echo "No $_GET found.";
}
I would just add to what #Nerdi.org said.
Specifically the second part, instead of looping through the array you can use either array_intersect_key or array_diff_key
$theseOnly = array("postName", "postName2");
$get = array_intersect_key( $_GET, array_flip($theseOnly);
//Or
$get = array_diff_key( $_GET, array_flip($theseOnly);
array_intersect_key
array_intersect_key() returns an array containing all the entries of array1 which have keys that are present in all the arguments.
So this one returns only elements you put in $theseOnly
array_diff_key
Compares the keys from array1 against the keys from array2 and returns the difference. This function is like array_diff() except the comparison is done on the keys instead of the values.
So this one returns the opposite or only elements you don't put in $theseOnly
And
array_flip
array_flip() returns an array in flip order, i.e. keys from array become values and values from array become keys.
This just takes the array of names with no keys (it has numeric keys by default), and swaps the key and the value, so
$theseOnly = array_flip(array("postName", "postName2"));
//becomes
$theseOnly = array("postName"=>0, "postName2"=>1);
We need the keys this way so they match what's in the $_GET array. We could always write the array that way, but if your lazy like me then you can just flip it.
session_start();
if(!isset($_SESSION['TestArray'])) $_SESSION['TestArray'] = array();
if(is_array($_GET)){
$_SESSION['TestArray'][] = $_GET;
}
print_r($_SESSION['TestArray']);
Thanks everybody for helping! This worked for me!
PHP has plenty of useful functions and Im wondering if Im overlooking one that has already been built.
Lets say you have an array such as:
$first_array = array("Name"=>"Angela", "Age"=>24);
and you wanted to grab the keys from the first array to create a second array (which could then be pushed into a third array). So you need to create:
$second_array = array("Name", "Age");
Is there a way to achieve this result without this loop?:
foreach($first_array as $k=>$v){
array_push($second_array, $k);
}
This should do it:
array_keys($first_array);
Use array_keys($first_array) to get the array of all the keys in the $first_array
I have an array that is associative that I have decoded from a json json_decode second value true and looks like
Array (
[test] => Array
(
[start] => 1358766000
[end] => 1358775000
[start_day] => 21
[end_day] => 21
)
)
But for some reason when I do $array[0] I get null? How can I get the array by index? Not by key name?
array_values() will give you all the values in an array with keys renumbered from 0.
The first level of the array is not numerical, it's an associative array. You need to do:
$array['test']['start']
Alternatively, to get the first element:
reset($array);
$first_key = key($array);
print_r($array[$first_key]);
You could use current.
$first = current($array); // get the first element (in your case, 'test')
var_dump($first);
This is by design . . . your JSON used a key (apparently test), which contained a JSON object. The keys are preserved when you do a json_decode. You can't access by index, though you could loop through the whole thing using a foreach.
From your comment, it sounds like you want to access previous and next elements from an associative array. I don't know a way to do this directly, but a hackish way would be as follows:
$testArr = array('a'=>'10', 'b'=>'2', 'c'=>'4');
// get numeric index of the element of interest
$keys = array_keys($testArr);
$i = array_search('b', $keys);
// get key of next element
$nextElementKey = $keys[$i+1];
// next element value
$nextElementValue = $testArry[$nextElementKey];
// get key of previous element
$prevElementKey = $keys[$i-1];
// prev value
$[prevElementValue = $testArry[$prevElementKey];
You'd probably want to add some error checking around the previous and next key calculations to handle the first and last values.
If you don't care about the data in the key, Ignacio's solution using array_keys is much more efficient.
This might sounds like a silly question. How do I get the 1st value of an array without knowing in advance if the array is associative or not?
In order to get the 1st element of an array I thought to do this:
function Get1stArrayValue($arr) { return current($arr); }
is it ok?
Could it create issues if array internal pointer was moved before function call?
Is there a better/smarter/fatser way to do it?
Thanks!
A better idea may be to use reset which "rewinds array's internal pointer to the first element and returns the value of the first array element"
Example:
function Get1stArrayValue($arr) { return reset($arr); }
As #therefromhere pointed out in the comment below, this solution is not ideal as it changes the state of the internal pointer. However, I don't think it is much of an issue as other functions such as array_pop also reset it.
The main concern that it couldn't be used when iterating over an array isn't an problem as foreach operates on a copy of the array. The PHP manual states:
Unless the array is referenced, foreach operates on a copy of the specified array and not the array itself.
This can be shown using some simple test code:
$arr = array("a", "b", "c", "d");
foreach ( $arr as $val ){
echo reset($arr) . " - " . $val . "\n";
}
Result:
a - a
a - b
a - c
a - d
To get the first element for any array, you need to reset the pointer first.
http://ca3.php.net/reset
function Get1stArrayValue($arr) {
return reset($arr);
}
If you don't mind losing the first element from the array, you can also use
array_shift() - shifts the first value of the array off and returns it, shortening the array by one element and moving everything down. All numerical array keys will be modified to start counting from zero while literal keys won't be touched.
Or you could wrap the array into an ArrayIterator and use seek:
$array = array("foo" => "apple", "banana", "cherry", "damson", "elderberry");
$iterator = new ArrayIterator($array);
$iterator->seek(0);
echo $iterator->current(); // apple
If this is not an option either, use one of the other suggestions.