Skip to content
This repository
Browse code

added a batch filter

  • Loading branch information...
commit a50bc8c95be668c35cda5a6efc6a1e8413d52670 1 parent ac86c63
Fabien Potencier authored February 21, 2013
2  CHANGELOG
... ...
@@ -1,6 +1,6 @@
1 1
 * 1.12.3 (2013-XX-XX)
2 2
 
3  
- * n/a
  3
+ * added a batch filter
4 4
 
5 5
 * 1.12.2 (2013-02-09)
6 6
 
45  doc/filters/batch.test
... ...
@@ -0,0 +1,45 @@
  1
+``batch``
  2
+=========
  3
+
  4
+.. versionadded:: 1.12.3
  5
+    The batch filter was added in Twig 1.12.3.
  6
+
  7
+The ``batch`` filter "batches" items by returning a list of lists with the
  8
+given number of items. If you provide a second parameter, it is used to fill
  9
+missing items:
  10
+
  11
+.. code-block:: jinja
  12
+
  13
+    {% set items = ['a', 'b', 'c', 'd', 'e', 'f', 'g'] %}
  14
+
  15
+    <table>
  16
+    {% for row in items|batch(3, 'No item') %}
  17
+      <tr>
  18
+      {% for column in row %}
  19
+        <td>{{ column }}</td>
  20
+      {% endfor %}
  21
+      </tr>
  22
+    {% endfor %}
  23
+    </table>
  24
+
  25
+The above example will be rendered as:
  26
+
  27
+.. code-block:: jinja
  28
+
  29
+    <table>
  30
+      <tr>
  31
+          <td>a</td>
  32
+          <td>b</td>
  33
+          <td>c</td>
  34
+        </tr>
  35
+      <tr>
  36
+          <td>d</td>
  37
+          <td>e</td>
  38
+          <td>f</td>
  39
+        </tr>
  40
+      <tr>
  41
+          <td>g</td>
  42
+          <td>No item</td>
  43
+          <td>No item</td>
  44
+        </tr>
  45
+    </table>
1  doc/filters/index.rst
Source Rendered
@@ -33,3 +33,4 @@ Filters
33 33
     first
34 34
     last
35 35
     trim
  36
+    batch
28  lib/Twig/Extension/Core.php
@@ -152,6 +152,7 @@ public function getFilters()
152 152
             new Twig_SimpleFilter('split', 'twig_split_filter'),
153 153
             new Twig_SimpleFilter('sort', 'twig_sort_filter'),
154 154
             new Twig_SimpleFilter('merge', 'twig_array_merge'),
  155
+            new Twig_SimpleFilter('batch', 'twig_array_batch'),
155 156
 
156 157
             // string/array filters
157 158
             new Twig_SimpleFilter('reverse', 'twig_reverse_filter', array('needs_environment' => true)),
@@ -1307,3 +1308,30 @@ function twig_constant($constant, $object = null)
1307 1308
 
1308 1309
     return constant($constant);
1309 1310
 }
  1311
+
  1312
+/**
  1313
+ * Batches item.
  1314
+ *
  1315
+ * @param array   $items An array of items
  1316
+ * @param integer $size  The size of the batch
  1317
+ * @param string  $fill  A string to fill missing items
  1318
+ *
  1319
+ * @return array
  1320
+ */
  1321
+function twig_array_batch($items, $size, $fill = null)
  1322
+{
  1323
+    if ($items instanceof Traversable) {
  1324
+        $items = iterator_to_array($items, false);
  1325
+    }
  1326
+
  1327
+    $result = array_chunk($items, $size, true);
  1328
+
  1329
+    if (null !== $fill) {
  1330
+        $last = count($result) - 1;
  1331
+        while (count($result[$last]) < $size) {
  1332
+            $result[$last][] = $fill;
  1333
+        }
  1334
+    }
  1335
+
  1336
+    return $result;
  1337
+}
37  test/Twig/Tests/Fixtures/filters/batch.test
... ...
@@ -0,0 +1,37 @@
  1
+--TEST--
  2
+"batch" filter
  3
+--TEMPLATE--
  4
+<table>
  5
+{% for row in items|batch(3, '') %}
  6
+  <tr>
  7
+  {% for column in row %}
  8
+    <td>{{ column }}</td>
  9
+  {% endfor %}
  10
+  </tr>
  11
+{% endfor %}
  12
+</table>
  13
+--DATA--
  14
+return array('items' => array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'))
  15
+--EXPECT--
  16
+<table>
  17
+  <tr>
  18
+      <td>a</td>
  19
+      <td>b</td>
  20
+      <td>c</td>
  21
+    </tr>
  22
+  <tr>
  23
+      <td>d</td>
  24
+      <td>e</td>
  25
+      <td>f</td>
  26
+    </tr>
  27
+  <tr>
  28
+      <td>g</td>
  29
+      <td>h</td>
  30
+      <td>i</td>
  31
+    </tr>
  32
+  <tr>
  33
+      <td>j</td>
  34
+      <td></td>
  35
+      <td></td>
  36
+    </tr>
  37
+</table>

0 notes on commit a50bc8c

Christophe Coevoet

As you are adding new features, shouldn't it be versionned as 1.13 ?

Luiz “Felds” Liscia

Using array_merge and array_fill seems to be about 30% faster than looping.

I've made some tests.

Loop (1.10s)

<?php

$start = microtime(true);

$a = array();
$l = 100000;
$s = 10;
$t = "Lorem ipsum";

for ($i=0; $i<$l; $i++) {
    $b = array("lorem", "ipsum", "dolor");
    while (count($b) < $s) {
        $b[] = $t;
    }
}

var_dump(microtime(true) - $start);

Fill + Merge (0.75s)

<?php

$start = microtime(true);

$a = array();
$l = 100000;
$s = 10;
$t = "Lorem ipsum";

for ($i=0; $i<$l; $i++) {
    $b = array("lorem", "ipsum", "dolor");
    $b = array_merge($b, array_fill(0, $s - count($b), $t));
}

var_dump(microtime(true) - $start);
Please sign in to comment.
Something went wrong with that request. Please try again.