Jump to content


Photo

extracting arrays from multidimensional arrays based on values


  • Please log in to reply
9 replies to this topic

#1 silphium

silphium
  • New Members
  • Pip
  • Newbie
  • 5 posts

Posted 08 September 2006 - 07:54 PM

Data retrieved from MySQL sits in a multidimensional array: $categories. I want to loop through $categories and process records where the value in the third column is "foo". Then I want to do the same where the value in the third column is "bar". So I need to create two new arrays, $foo and $bar. But I can't seem to figure out how to do this, except by using multiple MySQL queries. It must be do-able in PHP without these extra queries (some kind of nested looping, I suppose). I've looked at functions like array_filter, but they require the first argument to be an array, but since I'm dealing with a multidimensional array, I feel like I'm stuck. Anyone? Any help greatly appreciated. ~s

#2 Barand

Barand
  • Moderators
  • Sen . ( ile || sei )
  • 18,017 posts

Posted 08 September 2006 - 10:07 PM

If you want to use array_filter()
<?php
$categories = array (
        array (1, 11, 'foo'),
        array (2, 22, 'bar'),
        array (3, 33, 'foo'),
        array (4, 44, 'bar'),
);

function myfilter ($var) {
    global $gFilter;
    return $var[2] == $gFilter;
}

$gFilter = 'foo';
$foo = array_filter($categories, 'myfilter');
$gFilter = 'bar';
$bar = array_filter($categories, 'myfilter');

// check results
echo '<pre>', print_r($foo, true), '</pre>';
echo '<pre>', print_r($bar, true), '</pre>';
?>

Or
<?php
foreach ($categories as $data) {
    switch ($data[2]) {
    case 'foo' : $foo[] = $data; break;
    case 'bar' : $bar[] = $data; break;
    } 
}
?>

If you are still using mysql_ functions, STOP! Use mysqli_ or PDO. The longer you leave it the more you will have to rewrite.

Donations gratefully received






moon.png

|baaGrid| easy data tables - and more
|baaChart| easy line, column and pie charts

#3 roopurt18

roopurt18
  • Staff Alumni
  • Advanced Member
  • 3,749 posts
  • LocationCalifornia, southern

Posted 08 September 2006 - 10:26 PM

Why not do something like:

$cols = Array('foo', 'bar', 'qwerty', 'wysiwyg');
foreach($cols as $col){
  $tmp_col = addslashes($col);
  $sql = "SELECT * FROM table WHERE col='{$tmp_col}'";
  $q = mysql_query($sql);
  while($record = mysql_fetch_assoc($q)){
    $Results[$col] = ProcessRow($Results[$col], $record);
  }
}
From my experience, it's best to offload as much logic into SQL as possible.  If it provides the functionality, why not take advantage of it?
PHP Forms : Part I | Part II

JavaScript: Singleton

http://www.rbredlau.com

#4 Barand

Barand
  • Moderators
  • Sen . ( ile || sei )
  • 18,017 posts

Posted 08 September 2006 - 10:32 PM

But as the slowest bit of a script is the db access, why have 4 queries when 1 will do?
If you are still using mysql_ functions, STOP! Use mysqli_ or PDO. The longer you leave it the more you will have to rewrite.

Donations gratefully received






moon.png

|baaGrid| easy data tables - and more
|baaChart| easy line, column and pie charts

#5 Barand

Barand
  • Moderators
  • Sen . ( ile || sei )
  • 18,017 posts

Posted 08 September 2006 - 11:57 PM

@roopurt18,

OTOH, if, for example, the aim was to get counts of records for "foo" and "bar" then I would agree with you, better to use MySQL and have

SELECT x, COUNT(*) FROM tablename GROUP BY x

than to retrieve all records and count them with PHP

a ) still a single query
b ) more efficient query than pulling all records

but I wouldn't create extra queries just for the sake of using MySQL functionality.
If you are still using mysql_ functions, STOP! Use mysqli_ or PDO. The longer you leave it the more you will have to rewrite.

Donations gratefully received






moon.png

|baaGrid| easy data tables - and more
|baaChart| easy line, column and pie charts

#6 silphium

silphium
  • New Members
  • Pip
  • Newbie
  • 5 posts

Posted 11 September 2006 - 02:31 PM

thank you, Barand. That's exactly what I was looking for -- almost. I neglected to mention that I don't want the keys preserved, which array_filter() does (sorry, my fault). I do have a function that resets the keys, so it's not a huge deal. But out of curiosity, is there a built-in function similar to array_filter() that does not preserve the keys?

As for MySQL queries vs. PHP, generally I prefer to minimize the number of queries.

Thanks again, ~s

#7 Jenk

Jenk
  • Members
  • PipPipPip
  • Advanced Member
  • 778 posts

Posted 11 September 2006 - 02:42 PM

Why not do something like:

$cols = Array('foo', 'bar', 'qwerty', 'wysiwyg');
foreach($cols as $col){
  $tmp_col = addslashes($col);
  $sql = "SELECT * FROM table WHERE col='{$tmp_col}'";
  $q = mysql_query($sql);
  while($record = mysql_fetch_assoc($q)){
    $Results[$col] = ProcessRow($Results[$col], $record);
  }
}
From my experience, it's best to offload as much logic into SQL as possible.  If it provides the functionality, why not take advantage of it?

That is only true if you can execute as much of the query as possible within a single query.

What Barand suggested is best, or perhaps:

<?php
foreach ($data as $row) {
    if (!isset(${$row[2]})) ${$row[2]} = array();
    ${$row[2]}[] = $row;
}
?>

If() is to avoid errors.

#8 Barand

Barand
  • Moderators
  • Sen . ( ile || sei )
  • 18,017 posts

Posted 11 September 2006 - 02:51 PM

thank you, Barand. That's exactly what I was looking for -- almost. I neglected to mention that I don't want the keys preserved, which array_filter() does (sorry, my fault). I do have a function that resets the keys, so it's not a huge deal. But out of curiosity, is there a built-in function similar to array_filter() that does not preserve the keys?

As for MySQL queries vs. PHP, generally I prefer to minimize the number of queries.

Thanks again, ~s


$a = array_values($a) will reset keys.
If you are still using mysql_ functions, STOP! Use mysqli_ or PDO. The longer you leave it the more you will have to rewrite.

Donations gratefully received






moon.png

|baaGrid| easy data tables - and more
|baaChart| easy line, column and pie charts

#9 silphium

silphium
  • New Members
  • Pip
  • Newbie
  • 5 posts

Posted 15 September 2006 - 01:10 PM

Thank you Barand -- this solution works great. I have another question about dealing with multidimensional arrays (about which I'm feeling especially dense at the moment). Using the above scenario, how do you create (or extract) arrays of entire columns regardless of value? In other words, an array $foo that contains all of the values from the entire third column? Again, a second MySQL query would be easy, but I'm trying to get my brain wrapped around how to work with multidimensional arrays in PHP. I'll bet once I see see the answer, it will be so simple that I'll kick myself for not figuring it out on my own. ;-)

FWIW, once I have array $foo, I'll want to apply array_unique(), sort(), and similar functions.

thanks, ~s

#10 Barand

Barand
  • Moderators
  • Sen . ( ile || sei )
  • 18,017 posts

Posted 15 September 2006 - 08:22 PM

try
<?php
function extractColumn (&$array, $n) {
    $res = array();
    foreach ($array as $data)  {
        $res[] = $data[$n];
    }
    return $res;
}


$categories = array (
        array (1, 11, 'foo'),
        array (2, 22, 'bar'),
        array (3, 33, 'foo'),
        array (4, 44, 'bar'),
);

    // first col = 0, so third col is '2'
    
$foo = extractColumn($categories, 2);

    // view resultd
echo '<pre>', print_r($foo, true), '</pre>';
?>

If you are still using mysql_ functions, STOP! Use mysqli_ or PDO. The longer you leave it the more you will have to rewrite.

Donations gratefully received






moon.png

|baaGrid| easy data tables - and more
|baaChart| easy line, column and pie charts




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users