Get index from array according to a value inside - php

I have an array with this structure:
[items] => Array
(
[0] => items Object
(
[id:protected] => waHf9YHIEcYZAu6NmwQ9rOUZ6amsYME3
)
[1] => items Object
(
[id:protected] => waHf9YHIEcYZAu6NmwQ9rOUZ6amsYME3
)
)
Is there any way to get the index of the items according to the id:protected value? I want to unset this index based on the id value
I found a way bbut wanted to check if there is an option to not go trough all the array
foreach($items as $key => $val) {
if($val->getId() == $idIwanttodeelte) {
$index = $key;
}
}
//then unset according to index

You can remove items from an array that you are currently traversing without any issue:
foreach ($items as $key => $value) {
if ($value->getId() === $idToDelete) {
unset($items[$key]);
}
}

You could more easily use array_filter. This will create a new array without modifying the original
$filteredArray = array_filter($items, function($item) use ($idIwanttodeelte) {
return $item->getId() != $idIwanttodeelte;
});

Related

Remove the whole array elements, where array element key count < 2 in PHP

Below is my code that output this array:
// update users
$where_in = array('1102','');
$admin_data = $this->db->select('id,email,domain')->where_in('id',$where_in)->get('users')->result();
echo "<pre>";print_r($admin_data);
current output array
1102,
Array
(
[0] => stdClass Object
(
[id] => 1
)
)
1111,
Array
(
[0] => stdClass Object
(
[id] => 1132
)
[1] => stdClass Object
(
[id] => 1133
)
)
I am trying to accomplish by doing this, but not getting expected result.
foreach ($admin_data as $key) {
if (count($admin_data) < 2) {
unset($admin_data);
}
}
Expected result: I want to remove whole array element, where array key less than 2. I wish to get only array with more than 1 key count like below:
1111,
Array
(
[0] => stdClass Object
(
[id] => 1132
)
[1] => stdClass Object
(
[id] => 1133
)
)
I believe you are trying to unset elements within your "$admin_data" array, however you call unset on the array itself. If you pass the index of the array element into your loop, with the element itself, then you can check if the element has less than two inner elements, and unset that element accordingly.
$elementsToRemove = [];
foreach($admin_data as $index => $key) {
if (count($key) < 2) {
$elementsToRemove[] = $index;
}
}
$newArray = array_diff_key($admin_data, array_flip($elementsToRemove));
I'm not sure if I understood, but if you have an array of arrays and want to remove the inner arrays with less than 2 elements, you could do:
<?php
$original = [
["a"],
["b", "c"],
];
$filtered = array_filter(
$original,
function ($innerArray) {
return count($innerArray) >= 2;
}
);
print_r($filtered);
The result is
Array
(
[1] => Array
(
[0] => b
[1] => c
)
)
PHP Fiddle
Check again your code, it contains some logical problems:
foreach ($admin_data as $key) {
if (count($admin_data) < 2) {
unset($admin_data);
}
}
If $admin_data has one item, the if (count($admin_data) < 2) test is true and
unset($admin_data); is executed. That means (simplifying) that the all the contents of $admin_data are deleted.
If $admin_data has two or more items, the if (count($admin_data) < 2) test is never true. And it is so for each iteration.
Both cases are not logical, because you do not need the foreach loop for this test to work. Besides, you might not want to delete $admin_data contents.
What you need to do, is to iterate through $admin_data items, check the item to see if it is an array and if that array has one item, remove the item from the $admin_data array. Or you could create another array only with the valid items.
Here is a possible example of both:
/* unset the item if it is an array with one item */
foreach ($admin_data as $key => $value) {
if (is_array($value) && count($value) === 1) {
unset($admin_data[$key]);
}
}
/* create a new array with the valid items */
$valid_admin_data = [];
foreach ($admin_data as $key => $value) {
if (is_array($value) && count($value) > 1) {
$valid_admin_data[$key] = $value;
}
}
I would also suggest you to read again the foreach documentation. Also, be consistents with names of variables, since it helps avoid misunderstandings: for instance, foreach ($admin_data as $key) could be better named to foreach ($admin_data as $value), since with one variable, you extract the value of current item.

How to get a value from an array

Not sure why I can't this to work. My json is:
[values] => Array
(
[0] => Array
(
[field] => id1
[value] => 985
)
[1] => Array
(
[field] => id2
[value] => 6395
)
[2] => Array
(
[field] => memo
[value] => abcde
)
I simply want the values of id2
I tried:
foreach ($json['values'] as $values) {
foreach ($json as $key=>$data) {
if ($data['field'] == 'id2') {
$result = $data['value'];
print '<br>value: '.$result;
}
}
}
Thanks. I know this should be relatively simple and I'm sure I've done this correctly before.
there's no need for inner loop, after the first one $values already contain the exact array that you are looking for
foreach ($json['values'] as $values) // $values contain
{
if ($values['field'] == 'id2')
{
$result = $values['value'];
print '<br>value: '.$result;
}
}
foreach ($json['values'] as $values) { //you're looping your first array, puttin each row in a variable $values
foreach ($values as $key=>$data) { //you're looping inside values taking the array index $key and the value inside that index $data
if ($key == 'id2') { //test if $key (index) is = to id2
print '<br>value: '.$value; // print the value inside that index
}
}
}
this is just an explanation, to what is going wrong with your code, but as #Pawel_W there is no need for the second foreach loop you can directly test
if($values['field']=='id2'){ print $values['value'];}
I think you just need to use array_search.
And here is recursive array_search ;
Assuming there might be multiple fields with the same name and you want them all as array, here's an alternative take:
array_filter(array_map(function($item) { return $item['field'] == 'id2' ? $item['value'] : null; }, $json['values']));
If your field names are always unique and you just want a single scalar:
array_reduce($json['values'], function($current, $item) { return $item['field'] == 'id2' ? $item['value'] : $current; });
(note that this one is not ideal since it will walk all the array even if match is found in first element)
And here's a gist with both in this and function form + output.

PHP unsetting array in loop

I am trying to modify an existing array called field_data and delete the parent array of the key->value pair that has control == off. So in this example I would like to unset Array[1]. However it's not working, what am I doing wrong?
foreach ($field_data['0'] as &$subsection) {
foreach ($subsection as $key => $value)
{
if($key=='Control' && $value =='OFF')
{ echo 'match'; unset($subsection); }
}
return $field_data;
}
Field_data
----------
Array
(
[0] => Array
(
[0] => Array
(
[SECTION_ID] =>
[Control] => ON
[1] => Array
(
[SECTION_ID] =>
[Control] => OFF
)
)
)
You're trying to remove a variable that PHP is still using, specifically the array the inner loop is looping over.
The way you're checking you don't even need the inner loop. I would do something like this:
foreach( $field_data[0] as $skey => $svalue ) {
if( array_key_exists('Control', $svalue) && $svalue['Control'] == 'OFF' ) {
unset($field_data[0][$skey]);
}
}
try this...
unset($field_data[0][$subsection]);
I think you shouldn't modify array you're iterating.
Create an array of keys to remove instead, then iterate result and unset keys
$targets = array();
foreach( $field_data[0] as $skey => $svalue ) {
if( array_key_exists('Control', $svalue) && $svalue['Control'] == 'OFF' ) {
targets[] = $skey;
}
foreach($targets as $target)
{
unset($field_data[0][$target]);
}

Retrieve subarray of array by key value

I have the following array (example, real one is larger)
Array
(
[0] => Array
(
[984ab6aebd2777ff914e3e0170699c11] => Array
(
[id] => 984ab6aebd2777ff914e3e0170699c11
[message] => Test1
)
[1] => Array
(
[ca403872d513404291e914f0cad140de] => Array
(
[id] => ca403872d513404291e914f0cad140de
[message] => Test2
)
)
[2] => Array
(
[ca403872d513404291e914f0cad140de] => Array
(
[id] => ca403872d513404291e914f0cad140de
[message] => Test3
)
[3] => Array
(
[ca403872d513404291e914f0cad140de] => Array
(
[id] => ca403872d513404291e914f0cad140de
[message] => Test4
)
)
)
Now I want to somehow "access" the subarray with a given id, e.g. access the subarray with ID 984ab6aebd2777ff914e3e0170699c11 and then proceed to use this array in a foreach like this..
foreach ($array_with_specific_id as $event) {
echo $event['message'];
}
Is this possible?
Edit:
DB code to produce array in my model:
public function get_event_timeline($id)
{
$data = array();
foreach ($id as $result) {
$query = $this->db->query("SELECT * FROM event_timeline WHERE id = ?", array($result['id']));
foreach ($query->result_array() as $row)
{
array_push($data, array($row['id'] => $row));
}
}
return $data;
}
When populating your array from the database you can cerate an additional $index array like the following scheme:
$index = array (
'984ab6aebd2777ff914e3e0170699c11' => ReferenceToElementInData,
'ca403872d513404291e914f0cad140de' => ReferenceToElementInData,
// ...
)
This can give you quick access to the elements via their id without an additional foreach loop. Of course it will need additional memory, but this should be ok as you will only save refrences to the original data. However, test it.
Here comes an example:
public function get_event_timeline($id)
{
$data = array();
// create an additional index array
$index = array();
// counter
$c=0;
foreach ($id as $result) {
$query = $this->db->query("SELECT * FROM event_timeline WHERE id = ?", array($result['id']));
// every entry in the index is an array with references to entries in $data
$index[$result['id']] = array();
foreach ($query->result_array() as $row)
{
array_push($data, array($row['id'] => $row));
// create an entry in the current index
$index[$row['id']][] = &$data[$c];
$c++;
}
}
return array (
'data' => $data,
'index' => $index
);
}
Now you can access the elements via the index array without an additional foreach loop:
$entry = $index['984ab6aebd2777ff914e3e0170699c11'][0];
If there are multiple results per $id (as you mentioned in the comments you can access them using index greater then zero:
$entry = $index['984ab6aebd2777ff914e3e0170699c11'][1];
$entry = $index['984ab6aebd2777ff914e3e0170699c11'][2];
You can get the count of items per $id by calling
$number = count($index['984ab6aebd2777ff914e3e0170699c11']);
That's much the same like indexes that where used in databases to speed up queries.
I'd probably just get rid of the containing array as it seems unnecessary. However, you could do something like:
function get_message($specific_id, $arrays) {
foreach($arrays as $array) {
if(in_array($specific_id, $array)) {
return $array['message'];
}
}
}
I haven't had a chance to test this, but it should work.
function doTheJob($inputArray, $lookingFor) {
foreach ($inputArray as $subArray) {
foreach ($subArray as $subKey => $innerArray) {
if ($subKey == $lookingFor) {
return $innerArray;
}
}
}
return NULL;
}
Alternatively, you can use array_filter instead of outer foreach.

PHP -> Pick value from two-dimensional array based on key

I need to pick a value based on a specific key from an two-dimensional array, how would I do that?
I only know the key of the second level in the array in my code, and not in which array key it sits in level 1...
example:
Array
(
[0] => Array
(
[1] => http://stackoverflow.com/
)
[1] => Array
(
[0] => http://www.google.com
)
[2] => Array
(
[20567] => http://www.yahoo.com
)
)
Now I would like to pick the value of the key 20567 dynamically, I don't know where it sits in level 1, could be 0, 1,2 or any other key.
I hope I explained that well enough :)
You could use a RecursiveArrayIterator and RecursiveIteratorIterator:
$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($array));
foreach ($iterator as $key => $value) {
if ($key == 20567) {
var_dump($value);
break;
}
}
Example in a function:
function valueForKey($array, $key) {
$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($array));
foreach ($iterator as $arrayKey => $arrayValue) {
if ($arrayKey == $key) {
return $arrayValue
}
}
return null;
}
Another option is: (should work)
function getURLbyRedirects($redirectNumber , $array)
{
foreach($array as $lvl => $elems)
{
if(array_key_exists($redirectNumber , $elems))
return $elems[$redirectNumber];
}
return false;
}
By the way , consider using a different structre for this array, something like this:
Array (
[0] => Array
(
[url] => http://stackoverflow.com/
[redirects] => 2067
)

Categories