Getting position number from an array - php

If I have the following array in session, can I get a item position number in each [cat]:
Array
(
[0] => stdClass Object
(
[id] => 1
[cat] => 1
[que] => Description here.
)
[1] => stdClass Object
(
[id] => 2
[cat] => 1
[que] => Description here.
)
[2] => stdClass Object
(
[id] => 3
[cat] => 1
[que] => Description here.
)
)
For example the following will give me the second description, but how do I get that it has position #2 (out of 3) in [cat] == 1:
$item = $_SESSION['questions'][2]->que;
The actual array is much larger and has more than 1 [cat]. The count I am trying to get is withing each such group.

I'm sure you're looking for a more native way, but worse case scenario, you could add another element to hold the index value.

By adding a dummy entry at the beginning of the array:
array_unshift($_SESSION['questions'], array());
$item = $_SESSION['questions'][2]->que;

foreach($_SESSION['questions'] as $key=>$val)
{
if($val->id == 3)
echo $key;
}
//or
foreach($_SESSION['questions'] as $key=>$val)
{
if($val->que == "Description here.")
echo $key;
}
//do what ever you want

Related

merging array in CI 3

I want to merge two arrays in order to get the data as per my requirement.
I am posting my result, please have a look.
First array:
Array
(
[0] => Array
(
[km_range] => 300
[id] => 2
[car_id] => 14782
)
[1] => Array
(
[km_range] => 100
[id] => 3
[car_id] => 14781
)
[2] => Array
(
[km_range] => 300
[id] => 4
[car_id] => 14783
)
)
Second array:
Array
(
[0] => Array
(
[user_id] => 9c2e00508cb28eeb1023ef774b122e86
[car_id] => 14783
[status] => favourite
)
)
I want to merge the second array into the first one, where the value at key car_id matches the equivalent value; otherwise it will return that field as null.
Required output:
<pre>Array
(
[0] => Array
(
[km_range] => 300
[id] => 2
[car_id] => 14782
)
[1] => Array
(
[km_range] => 100
[id] => 3
[car_id] => 14781
)
[2] => Array
(
[km_range] => 300
[id] => 4
[car_id] => 14783
[fav_status] => favourite
)
)
Since the merge is so specific I would try something like this:
foreach ($array1 as $index => $a1):
foreach ($array2 as $a2):
if ($a1['car_id'] == $a2['car_id']):
if ($a2['status'] == "favourite"):
$array1[$index]['fav_status'] = "favourite";
endif;
endif;
endforeach;
endforeach;
You might be able to optimize the code more but this should be very easy to follow...
Another way to achieve this without using the index syntax is to reference the array elements in the foreach by-reference by prepending the ampersand operator:
foreach($firstArray as &$nestedArray1) {
foreach($secondArray as $nestedArray2) {
if ($nestedArray1['car_id'] == $nestedArray2['car_id']) {
$nestedArray1['fav_status'] = $nestedArray2['status'];
}
}
}
You can see it in action in this Playground example.
Technically you asked about merging the arrays. While the keys would be different between the input arrays and the desired output (i.e. "status" vs "fav_status"), array_merge() can be used to merge the arrays.
if ($nestedArray1['car_id'] == $nestedArray2['car_id']) {
$nestedArray1 = array_merge($nestedArray1, $nestedArray2);
}
Playground example.
Additionally the union operators (i.e. +, +=) can be used.
If you want to append array elements from the second array to the first array while not overwriting the elements from the first array and not re-indexing, use the + array union operator1
if ($nestedArray1['car_id'] == $nestedArray2['car_id']) {
$nestedArray1 += nestedArray1;
}
Playground example.
1http://php.net/manual/en/function.array-merge.php#example-5587

Sorting an StdClass Object Array by the values of another array

I have an StdClass Array. Each object is ordered like this (there are about 50 objects in the array, but I thought I'd just put one to show the structure):
stdClass Object (
[display_name] => Bob Simons
[post_title] => Lesson 1
[meta_value] => 100
[comment_approved] => passed
[c_num2] => 26
[term_id] => 3
)
I have another array that looks like this:
Array (
[0] => 3
[1] => 4
[2] => 5
[3] => 16
[4] => 17
[5] => 18
[6] => 19
[7] => 20
[8] => 21
)
The second array defines the sorting of the first one based on the [term_id] field. So essentially, everything with the [term_id] 3 should be at the top of the array, everything with the [term_id] 4 should be next, all based on that second array.
I am trying desperately to figure out how to do this, I've been looking at usort and the like but at a total loss.
I hope someone can help and will be really grateful.
Try this
$sortedArray = [];
foreach ($order as $termId) {
foreach ($objects as $object) {
if ($object->term_id == $termId) {
$sortedArray[] = $object;
}
}
}
$objects holds your stdClass instances and $order your list with the ordered term ids.
In the case the term_id should always order in an ascending way, you can use usort:
usort($objects, function ($obj1, $obj2) {
if ($obj1->term_id == $obj2->term_id) {
return 0;
}
return ($obj1->term_id < $obj2->term_id) ? -1 : 1;
});

echo a multidimensional array into multiple html table rows

I have a query that I'm running and it will output an unknown number of results. I want to display these results in a table of 5 columns. So I need the array print until the sixth result and then start a new row.
The way I tried to do it was to take the original array and chunk it into blocks of 5.
$display=array_chunk($row_Classrooms,5);
which gives me an array like this.
Array (
[0] => Array (
[0] => Array (
[id_room] => 1
[Name] => Classroom 1
[class] => Yes
)
[1] => Array (
[id_room] => 5
[Name] => Classroom 2
[class] => Yes
)
[2] => Array (
[id_room] => 6
[Name] => Classroom 3
[class] => Yes
)
[3] => Array (
[id_room] => 7
[Name] => Classroom 4
[class] => Yes
)
[4] => Array (
[id_room] => 8
[Name] => Classroom 5
[class] => Yes
)
)
[1] => Array (
[0] => Array (
[id_room] => 9
[Name] => Classroom 6
[class] => Yes
)
)
)
I'm then trying to echo this out with a pair of while loops, like such.
while ($rows = $display) {
echo '<tr>';
while ($class = $rows) {
echo'<td>'.$class['name'].'<br>
<input name="check'.$i.' type="checkbox" value="'.$class['id_room'].'></td>';
$i++;
}
echo '</tr>';
}
When I run this it apparently gets stuck in a never ending loop because nothing gets displayed but the browser just keeps chewing up more and more memory :)
The while statements are wrong. Have a look at here - in your while-statement you are always assigning the complete $display - not one entry.
You could try using while(($rows = array_shift($display)) !== false) - that will always get the first array item until there are no more items.
The same case in the second while-statement.
I ended up replacing the while loops with foreach loops instead which solved the issue.
foreach ($display as $rows) {
echo '<tr class="popup">';
foreach($rows as $class) {
if(isset($row_Rego)){
$exist=NULL;
$exist=array_search($class['id_room'], array_column($row_Rego, 'id_room'));
}

PHP Find value in object

I have a result of an SQL query that looks like this
Array
(
[0] => stdClass Object
(
[field_number] => 1
[value] => Joe
)
[1] => stdClass Object
(
[field_number] => 2
[value] => Bloggs
)
[2] => stdClass Object
(
[field_number] => 3
[value] => 12566
)
[3] => stdClass Object
(
[field_number] => 4
[value] => 2000-07-24
)
)
It wont always return all the fields as some are not required therefore not saved to the database.
I know that first name is stored with field number 1. How can I look this up in the object.
EG
$first_name = $result => field_number == 1
I know thats not right, but Im sure there must be a simple way to get this info?
Thanks
If the values in the array are not in order (eg array[0] does not always contain field_number 1) then you will need to iterate the array:
foreach($array as $item){
if($item->field_number==1){
$first_name = $item->value;
break;
}
}
However, if this is the result of an SQL query, probably you need to rewrite the query to give you data in a more useable form

Most Efficient Way to Delete Nested Array Element

Say I have the following:
Array(
[0] => Array
(
[id] => 1
[item] => first item
)
[1] => Array
(
[id] => 3
[item] => second item
)
[2] => Array
(
[id] => 5
[item] => third item
)
)
I want to delete the item with id = 5. I know I can loop through the array and unset, but I'm hoping for a more direct/efficient solution.
If you cannot make the IDs the keys of the outer array (then you could simply use unset($arr[5]);), looping over the array is indeed the way to dg.
foreach($arr as $key => $value) {
if($value['id'] === 5) {
unset($arr[$key]);
break;
}
}
Another option would be using array_filter - that's less efficient though since it creates a new array:
$arr = array_filter($arr, function($value) {
return $value['id'] !== 5;
});
Why don't you create the array with the keys set as the ID's? E.g:
Array(
[1] => Array
(
[id] => 1
[item] => first item
)
[3] => Array
(
[id] => 3
[item] => second item
)
[5] => Array
(
[id] => 5
[item] => third item
)
)
You can then write:
<?php
unset($array[5]); // Delete ID5
?>
For Multi level nested array
<?php
function remove_array_by_key($key,$nestedArray){
foreach($nestedArray as $k=>$v){
if(is_array($v)){
remove_array_by_key($key,$v);
} elseif($k==$key){
unset($nesterArray[$k]);
}
}
return $nestedArrat;
}
?>
The most efficient way would be to have 2 arrays.
ID => Index
Index => Object (your current array)
Search for ID in your ID => Index helper array and the value will be the Index for your main array, then unset them both.

Categories