More efficient access to an multi-dim array - php

I'm trying to nicely output a data array (with Kohana v2.3.4), and am thinking there has to be a more efficient and elegant way to do this. My array looks like this:
array('category_id' => value, 'category_title' => value, 'posts' => array( 'id' => value, 'title' => value, ... ))
And here's how I'm outputting it in my view (some array values are omitted from this example for the sake of simplicity):
foreach($data as $d) {
echo '<h3>'.$d['category_title'].'</h3>';
foreach($d['posts'][0] as $p) {
echo '<p>'.$p['title'].$p['id'].'</p>';
}
}
Is there a better way to go about this with the array I have?

You can't escape from using nested loop (unless if you use array_walk etc) but you can make do without using lots of string concatenation by taking advantage of variable substitution:
foreach($data as $d) {
echo "<h3>{$d['category_title']}</h3>";
foreach($d_posts[0] as $p) {
echo "<p>{$p['title']} {$p['id']}</p>";
}
}
You can also combine it with extract() for cleaner strings:
foreach($data as $d) {
extract($d, EXTR_PREFIX_ALL, 'd_');
echo "<h3>$d_category_title</h3>";
foreach($d_posts[0] as $p) {
extract($p, EXTR_PREFIX_ALL, 'p_');
echo "<p>$p_title $p_id</p>";
}
}

Apart from a minor error:
foreach ($data as $d) {
echo '<h3>'.$d['category_title'].'</h3>';
foreach($d['posts'] as $p) {
echo '<p>'.$p['title'].$p['id'].'</p>';
}
}
no there isn't.
What's your issue with a nested loop for this?

Related

php - Find array for which a key have a given value

I have an array of dictionnaries like:
$arr = array(
array(
'id' => '1',
'name' => 'machin',
),
array(
'id' => '2',
'name' => 'chouette',
),
);
How can I find the name of the array containing the id 2 (chouette) ?
Am I forced to reindex the array ?
Thank you all, aparently I'm forced to loop through the array (what I wanted to avoid), I thought that it were some lookup fonctions like Python. So I think I'll reindex with id.
Just find the index of array that contains the id you want to find.
SO has enough questions and answers on this topic available.
Assuming you have a big array with lots of data in your real application, it might be too slow (for your taste). In this case, you indeed need to modify the structure of your arrays, so you can look it up faster, e.g. by using the id as an index for the name (if you are only interested in the name).
As a for loop would be the best way to do this, I would suggest changing you array so that the id is the arrays index. For example:
$arr = array(
1 => 'machin',
2 => 'chouette',
);
This way you could just get the name for calling $arr[2]. No looping and keeping your program running in linear time.
$name;
foreach ($arr as $value){
if ( $value['id'] == 2 ){
$name = $value['name'];
break;
}
}
I would say that it might be very helpful to reindex the information. If the ID is unique try something like this:
$newarr = array();
for($i = 0;$i < count($arr);$i++){ $newarr[$arr[$i]['id']] = $arr[$i]['name']; }
The result would be:
$newarr = array('1'=>'machin','2'=>'chouette');
Then you can go trough the array with "foreach" like this:
foreach($newarr as $key => $value){
if($value == "machin"){
return $key;
}
}
But of course the same would work with your old array:
foreach($arr as $item){
if($item['name'] == "machin"){
return $item['id'];
}
}
It depends on what you are planning to do with the array ;-)
array_key_exist() is the function to check for keys. foreach will help you get down in the multidimensional array. This function will help you get the name element of an array and let you specify a different id value.
function findKey($bigArray, $idxVal) {
foreach($bigArray as $array) {
if(array_key_exists('id', $array) && $array['id'] == $idxVal) {
return $array['name'];
}
}
return false;
}
//Supply your array for $arr
print(findKey($arr, '2')); //"chouette"
It's a bit crude, but this would get you the name...
$name = false;
foreach($arr as $v) {
if($v['id'] == '2') {
$name = $v['name'];
break;
}
}
echo $name;
So no, you are not forced to reindex the array, but it would make things easier.

key and value array access in php

I am calling a function like:
get(array('id_person' => $person, 'ot' => $ot ));
In function How can I access the key and value as they are variable?
function get($where=array()) {
echo where[0];
echo where[1];
}
How to extract 'id_person' => $person, 'ot' => $ot without using foreach as I know how many key-values pairs I have inside function?
You can access them via $where['id_person'] / $where['ot'] if you know that they will always have these keys.
If you want to access the first and second element, you can do it like this
reset($where)
$first = current($where);
$second = next($where);
Couple ways. If you know what keys to expect, you can directly address $where['id_person']; Or you can extract them as local variables:
function get($where=array()) {
extract($where);
echo $id_person;
}
If you don't know what to expect, just loop through them:
foreach($where AS $key => $value) {
echo "I found $key which is $value!";
}
Just do $where['id_person'] and $where['ot'] like you do in JavaScript.
If you do not care about keys and want to use array as ordered array you can shift it.
function get($where=array()) {
$value1 = array_shift($where);
$value2 = array_shift($where);
}

PHP foreach of multidimensional array

I have an array and it has two arrays inside of it...I am able to access what I want for the first row by doing this...
print_r( $_SESSION['shopcart']['cart']['qty']);
How would I write that in a foreach?
Thanks,
J
foreach($_SESSION['shopcart']['cart']['qty'] as $value) {
echo $value;
}
you would do something like this:
to dump the array: $_SESSION['shopcart']['cart']
foreach($_SESSION['shopcart']['cart'] as $key=>$value){
echo $key." => ".$value."<br/>";
}
If you want to iterate through multiple dimensions, you can nest foreach as follows:
foreach($_SESSION['shopcart'] as $cart) {
foreach ($cart as $qty) {
// do something
}
}
Though I'd need a little more information about the array structure and what you really want to do in order to provide usable code, this is probably in the right ballpark.
I would recommend you you do do like this:
foreach($_SESSION['shopcart'] as $key=>$value){
if(is_array( $value ) ){
foreach($value => k1 => $v1){
//do something here if array
echo $k1." => ".$v1."<br/>";
}
}else{
//do something here if not array
}
}

PHP : how to use foreach loop inside an echo statement?

i am tring to put a loop to echo a number inside an echo ;
and i tried as bellow :
$array = array();
$result = mysql_query("SHOW TABLES FROM `st_db_1`");
while($row = mysql_fetch_row($result) ){
$result_tb = mysql_query("SELECT id FROM $row[0] LIMIT 1");
$row_tb=mysql_fetch_array($result_tb);
$array[] = $row[0];
$array2[] = $row_tb[0];
//checking for availbility of result_tb
/* if (!$result_tb) {
echo "DB Error, could not list tablesn";
echo 'MySQL Error: ' . mysql_error();
exit;
} */
}
natsort($array);
natsort($array2);
foreach ($array as $item[0] ) {
echo "<a href=show_cls_db.php?id= foreach ($array2 as $item2[0]){echo \"$item2[0]\"}>{$item[0]}<br/><a/>" ;
}
but php is not considering foreach loop inside that echo ;
please suggest me something
As mentioned by others, you cannot do loops inside a string. What you are trying to do can be achieved like this:
foreach ($array as $element) {
echo "<a href='show_cls_db.php?id=" . implode('', $array2) . "'>{$element}</a><br/>";
}
implode(...) concatenates all values of the array, with a separator, which can be an empty string too.
Notes:
I think you want <br /> outside of <a>...</a>
I don't see why you would want to used $item[0] as a temporary storage for traverser array elements (hence renamed to $element)
Just use implode instead of trying to loop the array,
foreach ($array as $item)
{
echo implode("",$array2);
}
other wise if you need to do other logic for each variable then you can do something like so:
foreach ($array as $item)
{
echo '<a href="show_details.php?';
foreach($something as $something_else)
{
echo $something_else;
}
echo '">Value</a>';
}
we would have to see the contents of the variables to understand what your trying to do.
As a wild guess I would think your array look's like:
array(
id => value
)
And as you was trying to access [0] within the value produced by the initial foreach, you might be trying to get the key and value separate, try something like this:
foreach($array as $id => $value)
{
echo $id; //This should be the index
echo $value; //This should be the value
}
foreach ($array as $item ) {
echo "<a href=\"show_cls_db.php?id=";
foreach ($array2 as $item2) { echo $item2[0]; }
echo "\">{$item[0]}<br/><a/>" ;
}
No offense but this code is... rough. Post it on codereview.stackexchange.com for some help re-factoring it. A quick tip for now would be to use PDO, and at the least, escape your inputs.
Anyway, as the answers have pointed out, you have simply echoed out a string with the "foreach" code inside it. Take it out of the string. I would probably use implode as RobertPitt suggested. Consider sorting and selecting your data from your database more efficiently by having mysql do the sorting. Don't use as $item[0] as that makes absolutely no sense at all. Name your variables clearly. Additionally, your href tag is malformed - you may not see the correct results even when you pull the foreach loop out of the echo, as your browser may render it all away. Make sure to put those quotes where they should be.

How do I have a more advanced array?

Basically I currently put a bunch of values into an array like so:
$flavors = array('Original','Cherry','Chocolate','Raspberry','Mango');
and from this I might execute a foreach like so:
foreach($flavors as $flav) {
echo doSomething($flav);
}
This all works a treat, until I get to the next stage of my learning which is to perhaps put 2 variables into doSomething().
For example, say I want to include the ingredients of Cherry e.g
echo doSomething($flav, $ingredient_of_this_flav);
I'm not sure if there is any way to go about doing this... I imagine I might need a second array entirely where I use the values above as my keys? e.g
$ingredients = array('Original' => 'boring stuff', 'Cherry' => 'cherries and other stuff') etc
And then I would doSomething() like so
foreach($flavors as $flav) {
echo doSomething($flav, $ingredients[$flav]);
}
I suppose I should go try this now. Is this the best approach or is there a better way to go about this? Ideally I would just have the one array not have to set $flavors and $ingredients.
Thanks for your time.
Arrays in php are associative, as you've noticed. And if I understand correctly, you're looking for the syntax to loop through each key/value pair?
foreach($ingredients as $flav => $ingredient) {
echo doSomething($flag, $ingredient);
}
Is this what you're looking for?
If you're looking to have complex values for each key, than you might want to look into objects, or the more brutal version, arrays of arrays.
$ingredients = array('Cherry' => array('Cherries', 'Other stuff'));
And your $ingredient in the loop above will be an array.
You can foreach over the keys and values of an array.
foreach ($ingredients as $flav => $ingredients)
{
echo doSomething($flav, $ingredients);
}
I would use an associative array (aka hash table) with a flavor => ingredients approach. Something like this:
$flavors = array ('Cherry' => array('stuff1', 'stuff2'),
'Mango' => array('stuff1', 'stuff3'));
echo $flavors['Cherry'][0]; // stuff1
foreach($flavors as $flavor => $ingredients)
{
print $flavor;
// $ingredients is an array so we need to loop through it
foreach($ingredients as $ingredient)
{
print $ingredient;
}
}
This is known as a nested loop and will print the flavor and each ingredient.
You are nearly there. I would set the array to be something like:
$ingredients = array('Original' => array('boring stuff', 'boring stuff2'), 'Cherry' => array('cherries', 'other stuff'));
And then loop as follows:
foreach($flavors as $flav => $ingredient) {
echo doSomething($flav, $ingredient);
}
Of course, it all depends on what you do in "doSomething()"

Categories