如何检查多维Twig数组的值?

时间:2015-02-23 10:16:30

标签: arrays twig

要简单检查数组是否包含某个值,我会这样做:

{% if myVar in someOtherArray|keys %}
...
{% endif %}

但是,我的数组是多维的。

$tasks = array(
    'someKey' => 'someValue',
    ...
    'tags' => array(
        '0' => array(
            'id'   => '20',
            'name' => 'someTag',
        ),
        '1' => array(
            'id'   => '30',
            'name' => 'someOtherTag',
        ),
    ),
);

我想要的是能够检查$tasks['tags']是否有标签ID 20.我希望我不要使用PHP数组格式来混淆你。

6 个答案:

答案 0 :(得分:6)

设置标志并使用循环。之后,您可以在条件中使用该标志。

{% set flag = 0 %}
{% for tag in tasks.tags %}
    {% if tag.id == "20" %}
        {% set flag = 1 %}
    {% endif %}
{% endfor %}
{{ flag }}

答案 1 :(得分:4)

如果有必要,这个更像是一个多维循环

   {% for animals in array %}

        {% set dogs = animals.dogs %}

        {% for dog in dogs %}
            {{ dump(dog.type) }}
        {% endfor%}

    {% endfor %}

答案 2 :(得分:2)

对于Twig中多维数组中的if语句。检查for循环,然后检查if语句。

以下是Twig的简写:

x=x+1

---- 编辑 ----

FOR ELSE

要做++'1'。因此{% for tag in tasks.tags if tag.id == '20' %} here_if_true {% endfor %} 如果在整个else

中找不到任何内容,则此处为else
for

FOR-IF ELSE

可以组合{% for tag in tasks.tags %} here_if_true {% else %} if there was nothing found {% endfor %} if,但它与else循环中的if else不同。因为for适用于else而不适用于for

if

LIVE example

FOR-IF ELSE和IF ELSE

{% for tag in tasks.tags if tag.name == 'blue' %}      
    This will fire if in the FOR the tag.name that is blue
{% else %}
    This will fire if there were NO tag.name blue were found ENTIRE FOR!
{% endfor %}

LIVE example

TWIG documentation

答案 3 :(得分:1)

我发现自己是解决方案。没想到它如此简单。有时我猜我只是想让事情变得太复杂。

{% for tag in tasks.tags %}
    {% if tag.id == '20' %}
        This tag has ID 20
    {% endif %}
{% endfor %}

在我看来,这不是最有效的方式,但它现在对我有用。

修改

Yenne Info向我介绍了以下方法。它有点清洁。我不知道它是否能提高性能。

{% for tag in tasks.tags if tag.id == '20' %}
    Bingo! We've got a match
{% endfor %}

答案 4 :(得分:1)

在树枝中设置标志

{% set flag = 0 %}

{% for tag in tasks.tags %}
    {% if tag.id == "20" %}
        {% set flag = 1 %}
    {% endif %}
{% endfor %}

{% if flag == 1 %}
    //do something
{% endif %}

在PHP中创建Custom Filter

要减少模板中的代码,twig可以创建自定义过滤器。要实现更通用的功能,您只需使用变量变量名称,并使用属性名称作为另一个参数。

<强> PHP

$filter = new Twig_SimpleFilter('inTags', function ($tags, $needle) {
    $match = false;
    foreach($tags as $tag){
        if(in_array($needle, $tag)){
            $match = true;
            break;
        }
    }
    return $match;
});

$twig = new Twig_Environment($loader);
$twig->addFilter($filter);

<强>枝条

{% if tasks.tags|inTags(20) %}
    //do something
{% endif %}

答案 5 :(得分:1)

{% if myVar is xpath_aware('//tags/*[id=20]') %}

上下文

如果你要在任意深度阵列上做条件,为什么不使用xpath的力量呢?毕竟,数组不过是一个非序列化的XML字符串!

所以,以下数组:

$data = array(
    'someKey' => 'someValue',
    'foo'     => 'bar',
    'hello'   => array(
        'world' => true,
        'tags'  => array(
            '0' => array(
                'id'   => '20',
                'name' => 'someTag',
            ),
            '1' => array(
                'id'   => '30',
                'name' => 'someOtherTag',
            ),
        ),
    ),
);

是XML字符串的等价物(修复以避免使用数字标记):

<data>
    <someKey>someValue</someKey>
    <foo>bar</foo>
    <hello>
        <world>1</world>
        <tags>
            <item0>
                <id>20</id>
                <name>someTag</name>
            </item0>
            <item1>
                <id>30</id>
                <name>someOtherTag</name>
            </item1>
        </tags>
    </hello>
</data>

并且您想知道您的数组是否与以下xpath表达式匹配:

//tags/*[id=20]

实施

我们创建一个新的twig Test,它将我们的数组转换为SimpleXMLElement对象,并使用SimpleXMLElement::xpath()检查给定的xpath是否匹配。

$test = new Twig_SimpleTest('xpath_aware', function (array $data, $path) {
    $xml = new SimpleXMLElement('<?xml version="1.0"?><data></data>');
    array_to_xml($data, $xml); // see full implementation below

    return array() !== $xml->xpath($path);
});

我们现在可以在Twig中运行以下测试:

{% if myVar is xpath_aware('//tags/*[id=20]') %}

完整的可执行实现:

xpath_test.php

<?php

include (__DIR__.'/vendor/autoload.php');

$context = array(
    'myVar' => array(
        'someKey' => 'someValue',
        'foo'     => 'bar',
        'hello'   => array(
            'world' => true,
            'tags'  => array(
                '0' => array(
                    'id'   => '20',
                    'name' => 'someTag',
                ),
                '1' => array(
                    'id'   => '30',
                    'name' => 'someOtherTag',
                ),
            ),
        ),
    ),
);

// http://stackoverflow.com/a/5965940/731138
function array_to_xml($data, &$xml_data)
{
    foreach ($data as $key => $value) {
        if (is_array($value)) {
            if (is_numeric($key)) {
                $key = 'item'.$key; //dealing with <0/>..<n/> issues
            }
            $subnode = $xml_data->addChild($key);
            array_to_xml($value, $subnode);
        } else {
            $xml_data->addChild("$key", htmlspecialchars("$value"));
        }
    }
}

$twig = new Twig_Environment(new Twig_Loader_Array([]));

$test = new Twig_SimpleTest('xpath_aware', function (array $data, $path) {
    $xml = new SimpleXMLElement('<?xml version="1.0"?><data></data>');
    array_to_xml($data, $xml);

    return array() !== $xml->xpath($path);
});

$twig->addTest($test);

$source = <<< EOT
{% if myVar is xpath_aware('//tags/*[id=20]') %}
It matches!
{% endif %}
EOT;

$template = $twig->createTemplate($source);
echo $template->display($context);

要运行它

composer require twig/twig
php xpath_test.php