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

 

Link to comment
Share on other sites

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;
  }
}

Link to comment
Share on other sites

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

 

 

 

Link to comment
Share on other sites

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;
}
?>

Link to comment
Share on other sites

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

 

Link to comment
Share on other sites

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 :)

 

Link to comment
Share on other sites

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

 

 

 

Link to comment
Share on other sites

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));
}

Link to comment
Share on other sites

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

 

 

 

 

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • 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.