Page 1 of 1

find the first and last occurence of each value in 2d array

Posted: Tue Feb 03, 2009 4:24 pm
by post_phobic
Hey all, heres the deal - I have a 2 dimensional array pulled straight out of a mysql table that looks something like this:
Array (
Array( 1 , 330 )
Array( 1 , 331 )
Array( 1 , 332 )
Array( 12 , 444)
Array( 12 , 445)
Array( 33 , 555)
Array( 33 , 556)
Array( 33 , 557)
Array( 33 , 558)
)

(The first value of the 2nd array(s) will always be in order, 1,12,33,99, ... etc)

My end goal is to end up with an array that looks like this:
Array (
Array( 1 , 330 , 'start')
Array( 1 , 331 , ' ' )
Array( 1 , 332 , 'end')
Array( 12 , 444, 'start')
Array( 12 , 445, 'end')
Array( 33 , 555, 'start')
Array( 33 , 556, ' ' )
Array( 33 , 557, ' ' )
Array( 33 , 558, 'end' )
)

I'm used to writing database code so if you think of this as a table I just want to identify the first and last occurence of each integer in the first column. I started to attempt this by myself but ended up creating lots of smaller arrays and I began to wonder about the efficiency of my approach and whether there were some well-known methods of solving problems like this that would be unfamiliar to someone without a formal computer background like myself. I can't write a mysql sproc for this because I don't have permissions on my server :(

Ultimately I would use 'end' and 'start' values in the final array to place my encapsulating div and /div tags respectively around the values within each array. This would be soo easy for me in t-sql but I am trying to get out of that habit.

Anyone have a solution or an alternative approach to suggest? [crossing fingers...]

Also, I am not creating a 3 dimensional array out of this because I wasn't very confident that I could output a 3 dimensional array in SMARTY - maybe I am wrong here? But for the sake of science and human progress in general I am still sort of curious what the solution would be to my above question without using a 3 dimensional array...

Re: find the first and last occurence of each value in 2d array

Posted: Tue Feb 03, 2009 4:44 pm
by VladSun

Code: Select all

$count = count($array);
$i = 0;
while ($i < $count -1 )
{
    if ($array[$i + 1][1] - $array[$i][1] > 1)
    {
        $array[$i][2] = 'end';
        $array[$i + 1][2] = 'start';
        ++$i;
    }   
    ++$i;
}
if (empty($array[0][2]))
    $array[0][2] = 'start';
 
if (empty($array[$count-1][2]))
    $array[$count-1][2] = 'end'; 
EDIT: Better way :)
EDIT 2: First and last elements handling.

Re: find the first and last occurence of each value in 2d array

Posted: Tue Feb 03, 2009 5:02 pm
by VladSun
It's not clear yet what you'll do with cases like these:

Code: Select all

Array (
Array( 0 , 200, '????')
Array( 1 , 330 , 'start')
Array( 1 , 331 , ' ' )
Array( 1 , 332 , 'end')
Array( 12 , 444, 'start')
Array( 12 , 445, 'end')
Array( 12 , 500, '????')
Array( 33 , 555, 'start')
Array( 33 , 556, ' ' )
Array( 33 , 557, ' ' )
Array( 33 , 558, 'end' )
)
 

Re: find the first and last occurence of each value in 2d array

Posted: Tue Feb 03, 2009 6:18 pm
by post_phobic
Awesome, thank you so much for that VladSun ... I am feeling quite enlightened right now. I've been trying to figure this out all morning so this is a huge relief. :D

What I will then be doing is outputting this array to SMARTY and calling it like this:

Code: Select all

 
{section name=templates loop=$templates start=0  step=1}
 
   {if $templates[templates].StartEndIndicator== 'start'}
      <div class="whatever">
   {/if}
 
      {$templates[templates].SomeTextHere}
 
   {if $templates[templates].StartEndIndicator== 'end'}
      </div>
   {/if}
 
{/section}
 
So :

<div class="whatever">
330
331
332
</div>
<div class="whatever">
444
445
</div>

etc..

Hopefully that makes sense. If not, feel free to save me from making another terrible programming mistake!

Re: find the first and last occurence of each value in 2d array

Posted: Tue Feb 03, 2009 6:21 pm
by VladSun
I don't use SMARTY (or any other template system), so I can't help you with that.

But still you need to think about what I've asked in my previous post.

Re: find the first and last occurence of each value in 2d array

Posted: Tue Feb 03, 2009 7:10 pm
by post_phobic
Hmm, I thought of another scenario too, so that would leave me with these scenarios:

A - what I just thought of:
Array (
Array( 1 , 330 , 'start')
Array( 1 , 331 , ' ' )
Array( 1 , 332 , '??')
Array( 2 , 333 , '??')
Array( 2 , 334 , ' ' )
Array( 2 , 335 , 'end')
)

B - what you pointed out:
Array (
Array( 1 , 330 , 'start')
Array( 1 , 331 , ' ' )
Array( 1 , 332 , 'end')
Array( 5 , 500, '????')
Array( 6 , 600, 'start')
Array( 6 , 601, 'end')
)

Regarding A, I may just change your line of code from

Code: Select all

if ($array[$i + 1][1] - $array[$i][1] > 1)
to:

Code: Select all

if ($array[$i + 1][0] - $array[$i][0] > 0)
But due to B I think I will add another if statement so it will look like

Code: Select all

 
if ($array[$i + 1][0] - $array[$i][0] > 0) 
{
if ($array[$i + 2][0] - $array[$i+1][0] > 0)
$array[$i][2] = 'exception';
} else {
$array[$i][2] = 'end';
$array[$i + 1][2] = 'start';
}
 
Array (
Array( 1 , 330 , 'start')
Array( 1 , 331 , ' ' )
Array( 1 , 332 , 'end')
Array( 5 , 500, 'exception')
Array( 6 , 600, 'start')
Array( 6 , 601, 'end')
)

I might not have explained the problem 100% clear in my original post, but the insight you gave is enough for me to figure the rest i think =P