This question already has answers here:
Deleting an element from an array in PHP
(25 answers)
Closed 8 years ago.
I want to search an associative array and when I find a value, delete that part of the array.
Here is a sample of my array:
Array
(
[0] => Array
(
[id] => 2918
[schoolname] => Albany Medical College
[AppService] => 16295C0C51D8318C2
)
[1] => Array
(
[id] => 2919
[schoolname] => Albert Einstein College of Medicine
[AppService] => 16295C0C51D8318C2
)
[2] => Array
(
[id] => 2920
[schoolname] => Baylor College of Medicine
[AppService] => 16295C0C51D8318C2
)
}
What I want to do is find the value 16295C0C51D8318C2 in the AppService and then delete that part of the array. So, for example, if that code was to run on the above array, it was empty out the entire array since the logic matches everything in that array.
Here is my code so far:
foreach($this->schs_raw as $object) {
if($object['AppService'] == "16295C0C51D8318C2") {
unset($object);
}
}
array_filter will help (http://php.net/manual/en/function.array-filter.php)
$yourFilteredArray = array_filter(
$this->schs_raw,
function($var) {
return $object['AppService'] != "16295C0C51D8318C2"
}
);
Try like this:
foreach ($this->schs_raw as &$object) {
if($object['AppService'] == "16295C0C51D8318C2") {
unset($object);
}
}
Eventually:
foreach ($this->schs_raw as $k => $object) {
if($object['AppService'] == "16295C0C51D8318C2") {
unset($this->schs_raw[$k]);
}
}
Try this:
foreach($this->schs_raw as $key=>$object) {
if($object['AppService'] == "16295C0C51D8318C2") {
unset($this->schs_raw[$key]); // unset the array using appropriate index
break; // to exit loop after removing first item
}
}
Why not create a new array? If match not found, add index to new array... If it is found, don't add it. Your new array will only contain the data you want.
Related
This question already has answers here:
Looping a multidimensional array in php
(3 answers)
How to load Google Maps in wpf window?
(2 answers)
Closed 5 years ago.
i have arrays like this
Any idea how to access #items subset with foreach or somthing fast like this?
Array
(
[0] => Array
(
[#theme] => item_list
[#items] => Array
(
[0] => Array
(
[nid] => 1
[changed] => 1514034947
[title] => TITLE 1
)
[1] => Array
(
[nid] => 2
[changed] => 1514034947
[title] => TITLE 2
)
)
)
[1] => Array
(
[#theme] => pager
)
BEST
As your elements are located below 3 levels so you need to use foreach thrice like below:
foreach($data as $items_list){
foreach($items_list[#items] as $items){
foreach($items as $val){
echo $val['nid'];
}
}
}
You can simply count array everytime and add condition before foreach loop to check if further array exists or not.
Like you can count main array and add condition with while loop and then use foreach like below:
$count = 0;
while($count<count($array)){
foreach($array[$count]['#items'] as $items ){
foreach($items as $val){
echo $val['nid'];
}
}
$count = $count+1;
}
Before doing anything, its better if you debug your multiple arrays like below:
echo "<pre>"; print_r($array); die;
You can use a nested foreach to get the final item list from this array object...
foreach($data as $items_list)
{
foreach($items_list[#items] as $items)
{
// do something here....
}
}
Assuming the array structure is exactly as you posted here is something you can experiment with. I don't know what you want to do with each item so this example just prints out the elements of each one:
foreach( $array as $outerarray )
{
foreach( $outerarray['#items'] as $item )
{
echo "{$item['nid']} {$item['changed']} {$item['title']}\n";
}
}
I use PHPExcel to put elements of my Excel file into an array. I then do
print_r($worksheets);
Where $worksheets is the array created through PHPExcel. The output is
Array (
[enquiry] => Array (
[0] => Array (
[0] => 86.141.247.93
)
[1] => Array (
[0] => 188.141.76.143
)
[2] => Array (
[0] => 2.29.20.161
)
)
)
What I need to do is pass each of these IPs as a String to a function. So what I am trying is this
foreach($worksheets as $ip) {
$count = 0;
if ($SpamProtecter->CheckIP($ip[$count][0])) {
print_r("SPAM");
} else {
print_r("GOOD");
}
$count++;
}
The problem I have is that it only prints out one result. How can I pass each array element as a String to CheckIP?
Thanks
You have an intermediate level in your array. Remember, foreach iterates over the top level of elements. You have 3 tiers here
foreach($worksheets['enquiry'] as $ip) { //iterate tier 1
if ($SpamProtecter->CheckIP($ip[0])) { //grab tier 3
print_r("SPAM");
} else {
print_r("GOOD");
}
}
Your $worksheets array only has a single key: enquiry, which is why you're only getting a single result output. Try this:
foreach($worksheets['enquiry']) as $ip) {
if($SpamProtector->CheckIP($ip[0]) {
// ...
I think you can also get rid of that inner $count variable since it is not used anymore.
This could work
foreach($worksheets['enquiry'] as $ip) {
if ($SpamProtecter->CheckIP($ip[0])) {
print_r("SPAM");
} else {
print_r("GOOD");
}
}
array_walk works well in situtations where you want to perform an action on each element in an array.
array_walk($worksheets["enquiry"],
function ($a) use ($SpamProtecter) {
echo $SpamProtecter->CheckIP($a[0])?"GOOD":"BAD";
});
With the following array, how would I just print the last name?
Preferably I'd like to put it in the format print_r($array['LastName']) the problem is, the number is likely to change.
$array = Array
(
[0] => Array
(
[name] => FirstName
[value] => John
)
[1] => Array
(
[name] => LastName
[value] => Geoffrey
)
[2] => Array
(
[name] => MiddleName
[value] => Smith
)
)
I would normalize the array first:
$normalized = array();
foreach($array as $value) {
$normalized[$value['name']] = $value['value'];
}
Then you can just to:
echo $normalized['LastName'];
If you are not sure where the lastname lives, you could write a function to do this like this ...
function getValue($mykey, $myarray) {
foreach($myarray as $a) {
if($a['name'] == $mykey) {
return $a['value'];
}
}
}
Then you could use
print getValue('LastName', $array);
This array is not so easy to access because it contains several arrays which have the same key. if you know where the value is, you can use the position of the array to access the data, in your case that'd be $array[1][value]. if you don't know the position of the data you need you would have to loop through the arrays and check where it is.. there are several solutions to do that eg:
`foreach($array as $arr){
(if $arr['name'] == "lastName")
print_r($arr['value']
}`
I have a feeling this question must have been asked before on this site, but for the life of me I cannot find the exact equivalent.
I want to check for the presence of a specific value in a multidimensional PHP array. For example:
Array (
[0] =>
Array (
[id] => 1
[publishDate] => 2013-02-22 01:51:39
[visible] => 1
)
[1] =>
Array (
[id] => 4
[publishDate] => 2013-02-22 02:49:58
[visible] => 1
)
[2] =>
Array (
[id] => 7
[publishDate] => 2013-02-22 02:50:21
[visible] => 1
)
)
Does "1" exist under the id key? (It exists in the publishDate key and in the visible key, but I don't wish to check those fields.)
So basically "1", "4" and "7" would return TRUE. While everything else would return FALSE.
This must be possible, but array_search and array_key_exists don't seem to be giving me what I need.
Thanks.
Honestly (imo), your best bet would probably be to just write your own function.
function visibleID($array, $id)
{
foreach ($array as $entry)
{
if ($entry['id'] === $id)
return true;
}
return false;
}
I'm sure if you could write a more generic function if you wanted (ie pass the 'visiblity' key as func arg) but that's up to you.
You can write more generic function to check key value pair By extending above function :
function visibleID($array, $id)
{
foreach ($array as $entry)
{
if( is_array($entry) ) {
array_map('visibleID',$entry); //-------------call back function
} else {
if ($entry['id'] === $id)
return true;
}
}
return false;
}
//-------------this function will work on any dimension array even both array(homogeneous and hetrogeneous)
I know there are a lot of answers on multi-dimensional arrays but I couldn't find what I was looking for exactly. I'm new to PHP and can't quite get my head around some of the other examples to modify them. If someone could show me the way, it would be much appreciated.
An external service is passing me the following multidimensional array.
$mArray = Array (
[success] => 1
[errors] => 0
[data] => Array (
[0] => Array (
[email] => me#example.com
[id] => 123456
[email_type] => html
[ip_opt] => 10.10.1.1
[ip_signup] =>
[member_rating] => X
[info_changed] => 2011-08-17 08:56:51
[web_id] => 123456789
[language] =>
[merges] => Array (
[EMAIL] => me#example.com
[NAME] => Firstname
[LNAME] => Lastname
[ACCOUNT] => ACME Ltd
[ACCMANID] => 123456adc
[ACCMANTEL] => 1234 123456
[ACCMANMAIL] => an.other#example.com
[ACCMANFN] => Humpty
[ACCMANLN] => Dumpty
)
[status] => unknown
[timestamp] => 2011-08-17 08:56:51
[lists] => Array ( )
[geo] => Array ( )
[clients] => Array ( )
[static_segments] => Array ( )
)
)
)
The only information I'm interested in are the key/value pairs that are held in the array under the key name 'merges'. It's about the third array deep. The key name of the array will always be called merges but there's no guarantee that its location in the array won't be moved. The number of key/value pairs in the merges array is also changeable.
I think what I need is a function for array_walk_recursive($mArray, "myfunction", $search);, where $search holds the string for the Key name (merges) I'm looking for. It needs to walk the array until it finds the key, check that it holds an array and then (preserving the keys), return each key/value pair into a single array.
So, for clarity, the output of the function would return:
$sArray = Array (
[EMAIL] => me#example.com
[NAME] => Firstname
[LNAME] => Lastname
[ACCOUNT] => ACME Ltd
[ACCMANID] => 123456adc
[ACCMANTEL] => 1234 123456
[ACCMANMAIL] => an.other#example.com
[ACCMANFN] => Humpty
[ACCMANLN] => Dumpty
)
I can then move on to the next step in my project, which is to compare the keys in the single merges array to element IDs obtained from an HTML DOM Parser and replace the attribute values with those contained in the single array.
I probably need a foreach loop. I know I can use is_array to verify if $search is an array. It's joining it all together that I'm struggling with.
Thanks for your help.
Would this work?
function find_merges($arr)
{
foreach($arr as $key => $value){
if($key == "merges") return $value;
if(is_array($value)){
$ret = find_merges($value);
if($ret) return $ret;
}
}
return false;
}
It would do a depth-first search until you either ran out of keys or found one with the value merges. It won't check to see if merges is an array though. Try that and let me know if that works.
Here is a general purpose function that will work it's way through a nested array and return the value associated with the first occurance of the supplied key. It allows for integer or string keys. If no matching key is found it returns false.
// return the value a key in the supplied array
function get_keyval($arr,$mykey)
{
foreach($arr as $key => $value){
if((gettype($key) == gettype($mykey)) && ($key == $mykey)) {
return $value;
}
if(is_array($value)){
return get_keyval($value,$mykey);
}
}
return false;
}
// test it out
$myArray = get_keyval($suppliedArray, "merges");
foreach($myArray as $key => $value){
echo "$key = $value\n";
}
A recursive function can do this. Returns the array or FALSE on failure.
function search_sub_array ($array, $search = 'merges') {
if (!is_array($array)) return FALSE; // We're not interested in non-arrays
foreach ($array as $key => $val) { // loop through array elements
if (is_array($val)) { // We're still not interested in non-arrays
if ($key == $search) {
return $val; // We found it, return it
} else if (($result = search_sub_array($array)) !== FALSE) { // We found a sub-array, search that as well
return $result; // We found it, return it
}
}
}
return FALSE; // We didn't find it
}
// Example usage
if (($result = search_sub_array($myArray,'merges')) !== FALSE) {
echo "I found it! ".print_r($result,TRUE);
} else {
echo "I didn't find it :-(";
}
So you want to access an array within an array within an array?
$mergeArray = NULL;
foreach($mArray['data'] as $mmArray)
$mergeArray[] = $mmArray['merges'];
Something like that? If merges is always three deep down, I don't see why you need recursion. Otherwise see the other answers.
Here's another approach, mostly because I haven't used up my iterator quota yet today.
$search = new RegexIterator(
new RecursiveIteratorIterator(
new ParentIterator(new RecursiveArrayIterator($array)),
RecursiveIteratorIterator::SELF_FIRST),
'/^merges$/D', RegexIterator::MATCH, RegexIterator::USE_KEY
);
$search->rewind();
$merges = $search->current();
array_walk_recursive() is brilliant for this task! It doesn't care what level the key-value pairs are on and it only iterates the "leaf nodes" so there is not need to check if an element contains a string. Inside of the function, I am merely making a comparison on keys versus the array of needles to generate a one-dimensional result array ($sArray).
To be clear, I am making an assumption that you have predictable keys in your merges subarray.
Code: (Demo)
$needles=['EMAIL','NAME','LNAME','ACCOUNT','ACCMANID','ACCMANTEL','ACCMANMAIL','ACCMANFN','ACCMANLN'];
array_walk_recursive($mArray,function($v,$k)use(&$sArray,$needles){if(in_array($k,$needles))$sArray[$k]=$v;});
var_export($sArray);
Output:
array (
'EMAIL' => 'me#example.com',
'NAME' => 'Firstname',
'LNAME' => 'Lastname',
'ACCOUNT' => 'ACME Ltd',
'ACCMANID' => '123456adc',
'ACCMANTEL' => '1234 123456',
'ACCMANMAIL' => 'an.other#example.com',
'ACCMANFN' => 'Humpty',
'ACCMANLN' => 'Dumpty',
)