I have 3 td's in a portion of a table. Sometimes, the data coming in from the database is less than 3. I need a method that will lay-out the data precisely compared to a rank in the table.

Ideal situation:

array 
|-0
  |-name => Joe
  |-rank => 0
|-1
  |-name => Dick
  |-rank => 1
|-2
  |-name => Mike
  |-rank => 2

Yields:

<tr>
    <td data-rank="0">
        Joe
    </td>
    <td data-rank="1">
        Dick
    </td>
    <td data-rank="2">
        Mike
    </td>
</tr>

Problem situation:

array 
|-0
  |-name => Dick
  |-rank => 1
|-1
  |-name => Mike
  |-rank => 2

Yields:

<tr>
    <td data-rank="0">
        Dick
    </td>
    <td data-rank="1">
        Mike
    </td>
</tr>

Need:

<tr>
    <td data-rank="0">
        &nbsp;
    </td>
    <td data-rank="1">
        Dick
    </td>
    <td data-rank="2">
        Mike
    </td>
</tr>

This is the for loop I am running. I think I need the array function prev to move the pointer back but can not get my head around it.

for ($i=0; $i<3; $i++) {
    $a  = array("class"=>"genre", "data-rank"=>$i,"data-method"=>"update");
    $o .= $this->td_new($a);
    if ( array_key_exists($i, $r1) && ($r1[$i]['rank'] == $i)  ) {
        $o .= $r1[$i]['name'];
    } else {
        $o .= "&nbsp;";
        prev($r1);
    }
    $o .= $this->td_close();
}//for
return $o;

With the above, I am ending up with 3 blank td's. Sub-functions like $this->td_open and $this->td_close work perfectly. Detail about exact output had been left out too keep things brief and focussed on where I need help. Instances the array is 3 keys, output is perfect.

Thanks for taking the time to read this.

Member Avatar for diafol

Maybe something like this...

$width = 3; //max columns
$output = '<tr>';
$r = [];
foreach($array as $item){
    $r[$item['rank']] = $item['name'];
}
for($i=0;$i<$width;$i++){
    $content = (isset($r[$i])) ? $r[$i] : "&nbsp;"; 
    $output .= "<td data-rank=\"$i\">$content</td>";
}
$output .= "</tr>";

This makes a lot of assumptions, with regard to the data coming in from $array.
Although this uses two loops - the arrays are v small and it should not be an issue. PHP array_* functions tend to be quite slow in comparison - so even though they make code more succinct, they are rarely quicker than loops.

Thanks diafol but your method is premised on redfining the array different from how it is when I query the database.

Member Avatar for diafol

I didn't think it was. I assumed from your example that rank could be either 0 or 1 or 2. That's why I mentioned:

This makes a lot of assumptions, with regard to the data coming in from $array.

So you're now saying that the 'rank' could be anything?

Member Avatar for diafol

This is an example output:

<?php
$array1 = [
    ['name'=>'Ben', 'rank'=>1],
    ['name'=>'Alun', 'rank'=>2]
];

$array2 = [
    ['name'=>'Ben', 'rank'=>0],
    ['name'=>'Alun', 'rank'=>1],
    ['name'=>'Llew', 'rank'=>2],
];

$array3 = [
    ['name'=>'Ben', 'rank'=>0],
    ['name'=>'Alun', 'rank'=>2]
];

$array4 = [
    ['name'=>'Ben', 'rank'=>0],
    ['name'=>'Alun', 'rank'=>1]
];

function makeRow($array)
{
    $width = 3; //max columns
    $output = '<tr>';
    $r = [];
    foreach ($array as $item) {
        $r[$item['rank']] = $item['name'];
    }
    for ($i = 0; $i < $width; $i++) {
        $content = (isset($r[$i])) ? $r[$i] : "&nbsp;";
        $output .= "<td data-rank=\"$i\">$content</td>";
    }
    $output .= "</tr>";
    return $output;
}
echo "<pre>";
echo htmlentities(makeRow($array1)) ."\n";
echo htmlentities(makeRow($array2)) ."\n";
echo htmlentities(makeRow($array3)) ."\n";
echo htmlentities(makeRow($array4)) ."\n";

And it works as I thought you wanted it:

<tr><td data-rank="0">&nbsp;</td><td data-rank="1">Ben</td><td data-rank="2">Alun</td></tr>
<tr><td data-rank="0">Ben</td><td data-rank="1">Alun</td><td data-rank="2">Llew</td></tr>
<tr><td data-rank="0">Ben</td><td data-rank="1">&nbsp;</td><td data-rank="2">Alun</td></tr>
<tr><td data-rank="0">Ben</td><td data-rank="1">Alun</td><td data-rank="2">&nbsp;</td></tr>

diafol,

My profound apologies for my earlier reply and thanks for your solution.

The first reply to you regarding this answer was before a few cups of tea to get started. That lack of tea combined with a fuzzy head from looking for and trying different solutions yesterday and I couldn't wrap my head around what you had posted.

Rectifying those things and looking at the above, BAM! it works. Thank you!

commented: Bam Bam goes Bam Bam Bam! +12
Member Avatar for diafol

You're very welcome. Glad it's sorted :)

I dont have answer, but thumbs UP for Dick hahahaha :D

commented: Now google diafol. +0
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.