Jump to content

searching in multidimensional array for a date


amosse

Recommended Posts

Hello to everybody,

 

I am using the following function in order to search  in multi-dimensional array

function array_search_recursive($data0, $FinRecSet, $a=0, $nodes_temp=array()){
global $nodes_found;
  $a++;
  foreach ($FinRecSet as $key1=>$value1) {
    $nodes_temp[$a] = $key1;
    if (is_array($value1)){    
      array_search_recursive($data0, $value1, $a, $nodes_temp);
    }
    else if ($value1 === $data0){
      $nodes_found = $nodes_temp[1];
    }
  } 
  return $nodes_found;
}

 

where

$data0 is a date (ex:'1-1-2008')

and $FinRecSet is an array containing financial entries

like this

Array (

[0] => Array ( [id] => 281 [Date] => 01-01-2008 [FCode] => A01 [Descr] => Prova [Debit] => 100.00 [RunDeb] => 2065300.64 [Credit] => 0.00 [RunCre] => 3020765.67 [RunBal] => -955465.03 [Rec] => 0 ) [1] => Array ( [id] => 282 [Date] => 01-01-2008 [FCode] => A02 [Descr] => Prova [Debit] => 120.00 [RunDeb] => 2065420.64 [Credit] => 0.00 [RunCre] => 3020765.67 [RunBal] => -955345.03 [Rec] => 0 ) ect....

 

when I run function I get exactely the last entry with date = '1-1-2008', problem is when I don't have entries on such date, for that I should modify function in order to get entry on older date available before $data0.

For example if $date0 = '1-1-2008'

and first entry is available only on '30-12-2007', how should I modify function?

 

Thank for your attention.

 

Amos

 

basicall you just need to add a line to save the "old date" value when the date doesn't match. However, it appears you need the most previous date - so you need to do a comparison each time. That would be very easy if your dates were in the format YYYYMMDD - you could do a numeric comprison. Since they are not you need to conver the string values to a timestamp

 

try this:

 

function array_search_recursive($data0, $FinRecSet, $a=0, $nodes_temp=array()){
global $nodes_found;
  $a++;
  foreach ($FinRecSet as $key1=>$value1) {
    $nodes_temp[$a] = $key1;
    if (is_array($value1)){    
      array_search_recursive($data0, $value1, $a, $nodes_temp);
    }
    else if ($value1 === $data0){
      $nodes_found = $nodes_temp[1];
    } else {
      $dateParts = explode('-', $value1);
      $date = $dateParts[2] . $dateParts[0] . $dateParts[1];
      if ($date > $date_last) {
        $date_last = $date;
        $nodes_found_last = $nodes_temp[1];
      }
    }
  }
  if ($nodes_found) {
    return $nodes_found;
  } else {
    $nodes_found_last;
  }
}

Many thanks for your replies.

 

If date format is a problem, from now on date format is YYYY-MM-DD I modified it.

 

I try to esplain behaviour of mjdamato proposal adding the following code lines:

$dateParts = explode('-', $value1)
print_r($dateParts);

I get explosion of all data array and not only key=>[][ 'Date' ]

 

when you write

if ($date > $date_last)

I think $date_last doesn't have value

 

Thank you again.

Amos

 

 

 

OK, I created my example based upon the original code yu posted. I see something that isn't making sense to me. See your original code with questions/comments

 

<?php
function array_search_recursive($data0, $FinRecSet, $a=0, $nodes_temp=array()){
global $nodes_found;
  $a++;
  foreach ($FinRecSet as $key1=>$value1) {
    $nodes_temp[$a] = $key1;
    if (is_array($value1)){    
      array_search_recursive($data0, $value1, $a, $nodes_temp);
    }
    else if ($value1 === $data0){
      //According to this it ALWAYS returns the $node_temp value with theindex of 1
      //Shouldn't it be the current $key1 value???
      $nodes_found = $nodes_temp[1];
    }
  } 
  return $nodes_found;
}
?>

Many thanks for your reply.

 

I tell you this function I got from array_search php official manual (first note at the bottom).

 

For my specific case I have to search in a bi-dimentional array  and I know from the beginning the structure, this one:

Array(

([0] = >Array ( [id] => 281 [Date] => 01-01-2008 [FCode] => A01 [Descr] => Prova [Debit] => 100.00 [RunDeb] => 2065300.64 [Credit] => 0.00 [RunCre] => 3020765.67 [RunBal] => -955465.03 [Rec] => 0 )

[1] = >Array ( [id] => 282 [Date] => 01-01-2008 [FCode] => A02 [Descr] => Prova [Debit] => 120.00 [RunDeb] => 2065420.64 [Credit] => 0.00 [RunCre] => 3020765.67 [RunBal] => -955345.03 [Rec] => 0 )

)

 

I modified the original example from:

function array_search_recursive($data0, $arrFinRecSet2, $a=0, $nodes_temp=array()){
global $nodes_found;
$a++;
foreach ($arrFinRecSet2 as $key1=>$value1) {
$nodes_temp[$a] = $key1;
if (is_array($value1)){
array_search_recursive($data0, $value1, $a, $nodes_temp);
}
else if ($value1 === $data0){
$nodes_found[] = $nodes_temp[$a];
}
} 
return $nodes_found;
} 

that returned me, for example with $data0 =  '2007-12-31'

Array ( [0] => Date [1] => Date ) , absolutely useless for me.

 

as follow:

function array_search_recursive($data0, $arrFinRecSet2, $a=0, $nodes_temp=array()){
global $nodes_found;
$a++;
foreach ($arrFinRecSet2 as $key1=>$value1) {
$nodes_temp[$a] = $value1;
if (is_array($value1)){
array_search_recursive($data0, $value1, $a, $nodes_temp);
}
else if ($value1 === $data0){
$nodes_found = $nodes_temp[1];
}
} 
return $nodes_found;
} 

the above function gives me with $data0 =  '2007-12-31':

Array ( [id] => 350 [Date] => 2007-12-31 [FCode] => A01 [Descr] => Prova [Debit] => 2341.87 [RunDeb] => 2067642.51 [Credit] => 0.00 [RunCre] => 3020765.67 [RunBal] => -953123.16 [Rec] => 0 )  exactely what I need (entry with highest Id for Date = '2007-12-31').

 

For replying to your questions I changed in $nodes_found = $nodes_temp[1];

because I get the above result, what I need. Otherwise I got:

 

with $nodes_found[] = $nodes_temp[$a];

Array ( [0] => 2007-12-31 [1] => 2007-12-31 )

 

with $nodes_found[] = $nodes_temp;

Array ( [0] => Array ( [1] => Array ( [id] => 311 [Date] => 2007-12-31 [FCode] => A01 [Descr] => Prova [Debit] => 100.00 [RunDeb] => 2065300.64 [Credit] => 0.00 [RunCre] => 3020765.67 [RunBal] => -955465.03 [Rec] => 0 ) [2] => 2007-12-31 ) [1] => Array ( [1] => Array ( [id] => 350 [Date] => 2007-12-31 [FCode] => A01 [Descr] => Prova [Debit] => 2341.87 [RunDeb] => 2067642.51 [Credit] => 0.00 [RunCre] => 3020765.67 [RunBal] => -953123.16 [Rec] => 0 ) [2] => 2007-12-31 ) )

but I need only entry with highest Id for that date (original query from which I get data is already ordered by date,id) and not all entries on $data0, and more I don't need key 2 with Date value repeted.

 

with $nodes_found = $nodes_temp;

Array ( [1] => Array ( [id] => 350 [Date] => 2007-12-31 [FCode] => A01 [Descr] => Prova [Debit] => 2341.87 [RunDeb] => 2067642.51 [Credit] => 0.00 [RunCre] => 3020765.67 [RunBal] => -953123.16 [Rec] => 0 ) [2] => 2007-12-31 )

I don't need key 2 with Date value repeted.

 

I hope my explication will be clear, I hope I will find a solution I am on key point on the development of my little project.

 

Thank you again.

Amos

 

I dun see why u need a recursive search function.

the data y show looks like a standard data set.

recursion comes when u have arrays in arrays in arrays, and must check up to the deepest nested array.

 

it looks like all u need is a simple function to search for id's with a specific date

 

function md_search($array, $fieldid, $what)
{
  foreach($array as $key => $item)
      if($item[$fieldid]==$what) $found[]=$key;
  return $found;
}

 

now ya can find yer data with

$keysofitems=md_search($array,'Date','2007-12-31');

which will return an array of keys :)

 

Many thanks for your reply.

 

Laffin,

You are right now function is more simple and works very well.

But problem still remain, in case $what is not available I have to look for most previous Date.

For examble if '2007-12-31' is not available, may be most previous date is '2007-12-27' or '2007-12-26',

how can I modify function in order to get most previous Date?

 

Any help will be realy very appreciate.

 

Thank you for your attention.

Amos

 

 

 

u can do this in the function or outside the function.

 

i will do it outside the function

 

$searchdate="2007-12-31";
$keysofitems=md_search($array,'Date',$searchdate);
if(empty($keysofitems)) {
   $searchdate = date("Y-m-d",strtotime($searchdate) - (60*60*24));
   $keysofitems=md_search($array,'Date',$searchdate);
}

 

as u can see, if we get no results, we take the search date, and subtract 1 day (60 secs * 60 Mins * 24 hrs). Which wud be the previous day of $date.

 

u can of course use a do loop to find the last date used

 

$searchdate="2007-12-31";
$counter=0;
do {
  $counter++;
  if($counter>30) break; // limit our back date search to 30 days
  $keysofitems=md_search($array,'Date',$searchdate);
  if(!empty($keysofitems)) break; // exit our loop;
   $searchdate = date("Y-m-d",strtotime($searchdate) - (60*60*24));
}

Many many thanks for you reply.

 

Finally I think I get it.

I try:

print_r(array_pop(arrStartBal($arrFinRecSet2,'Date',$data0)));

function arrStartBal($array, $fieldkey, $data0)
{
$searchdate=$data0;
$counter=0;
do {
  $counter++;
  if($counter>30) break; // limit our back date search to 30 days
  $keysofitems=md_search($array, $fieldkey, $searchdate);
  if(!empty($keysofitems)) break; // exit our loop;
  $searchdate = date("Y-m-d",strtotime($searchdate) - (60*60*24));
} while ($counter<=30);
$found = md_search($array, $fieldkey, $searchdate);
return $found;
}

function md_search($array, $fieldkey, $data0)
{
foreach($array as $key => $item)
    if($item[$fieldkey]==$data0) $found[]=$item;
return $found;
}

 

It seems to work very well.

 

Thank you Laffin.

Amos

 

 

 

 

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.