Show smallest and largest in a structure list

I would need to retrieve in a structure array the smallest value and the largest value.

Example (to display distances in km):

  • If only one piece of information: 100 km
  • If 2 or more information 100 km to 300 km

Equivalent to the min() or max() function of PHP.

Does something exist in kirby to facilitate the work?

No, but why don’t you want to use the native functions? But I’m not sure I understand, do you want to sort all items or pick min and max. Headline says sort, but then I don’t know what you want with min and max

Effectively, I want to display the smallest and largest in a list.

Could you provide the structure, please?

I want to manipulate “race_km”

          listing:
            label: Épreuves
            type: structure
            fields:
              race_title:
                label: Titre
                type: text
                width: 2/4
              race_km:
                label: Distance
                type: number
                placeholder: Kilomètres
                after: km
                step: .1
                width: 1/4

Template

                      <?php foreach($page->listing()->toStructure() as $item): ?>
                          <?php if ($item->race_km()):?>
                                    <?= $item->race_km()->min() ?> km
                          <?php endif ?>
                      <?php endforeach ?>
$raceKmItems = $page->listing()->toStructure()->pluck('race_km', ',', true);
$min         = min($raceKmItems);
$max         = max($raceKmItems);

Alternative:

$items = $page->listing()->toStructure()->sortBy('race_km', 'asc');
$min   = $items->first()?->race_km();
$max   = $items->last()?->race_km();

Agreed, that’s really well thought out.

Thanks very much

I don’t think without your help I would never have thought of doing this.

I am trying to think about how to manage the 2 conditions:

  • If a single line
  • If 2 or more lines

You can check if $min === $max, then you have only one item.

In the second example, you would have to filter out empty items first.

I had just done that.

Surely we can do better

                  <?php 
                      if ($page->listing()->toStructure()->isNotEmpty()):

                      $items = $page->listing()->toStructure()->sortBy('race_km', 'asc');
                      $min   = $items->first()->race_km();
                      $max   = $items->last()->race_km();
                  ?>
                      <?php if ($items->count() >= 2): ?>
                                <?= $min ?> à <?= $max ?> km
                      <?php else: ?>
                        <?= $min ?> km
                      <?php endif ?>
                    
                  <?php endif ?>

Even if you have two items, they can be the same?

 <?php if ($page->listing()->toStructure()->isNotEmpty()) {

    $items = $page->listing()->toStructure()->sortBy('race_km', 'asc')->filter(fn($item) => empty($item->race_km()->value()) === false);
    $min   = $items->first()->race_km();
    $max   = $items->last()->race_km();
    echo $min === $max ?  $min . ' km' : $min . ' à ' . $max . ' km';
}

You are right. It’s professional code. Thank you so much.

It could indeed happen that the distance is identical, but this is a rare case.

echo $min == $max ?

If I leave === it puts duplicates if identical.
If I put == it does not put the duplicate (strange).

However, there is one last error.

If I create a list and there is nothing in the race_km field there is an error page.

Call to a member function race_km() on null

Line : $min = $items_race_km->first()->race_km();

content/

Listing:

- 
  race_title: ""
  race_km: null

An idea ?

My original code used the null-safe operator (?->) to prevent this error, see above.

I also suggested filtering out the empty ones first! Assuming you are on PHP 8+.

I actually removed the “?” I did not know.

thank you, i will try tomorrow