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

时间:2022-11-19 13:31:26

To simply check if an array contains a certain value I would do:

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

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

However, my array is multi-dimensional.

但是,我的阵列是多维的。

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

What i would like is to be able to check if the $tasks['tags'] has tag id 20. I hope I'm not confusing you by using the PHP array format.

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

6 个解决方案

#1


5  

Set a flag and use a loop. Afterwards you can use the flag in if conditions.

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

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

#2


4  

this one is more like a multidimensional loop in case it's necessary

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

   {% for animals in array %}

        {% set dogs = animals.dogs %}

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

    {% endfor %}

#3


2  

For an if-statement within a multi-dimensional array in Twig. Check within the for-loop and then the if statement.

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

Here is the shorthand for this with Twig:

以下是Twig的简写:

{% for tag in tasks.tags if tag.id == '20' %}      
       here_if_true
{% endfor %}    

---- EDIT ----

----编辑----

FOR ELSE

对于ELSE

To do an else. So the else here is if nothing is found in the entire for:

做别的。所以这里的其他内容是,如果在整个过程中找不到任何内容:

{% for tag in tasks.tags %}    
       here_if_true
{% else %}
       if there was nothing found
{% endfor %}    

FOR-IF ELSE

FOR-IF ELSE

Making a combination of the if and else is possible, but it is NOT the same as an if else inside the for loop. Because the else is for the for and not for the if.

组合if和else是可能的,但它与for循环中的if else不同。因为else是for for而不是if。

{% 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

现场例子

FOR-IF ELSE and IF ELSE

FOR-IF ELSE和IF ELSE

{% for tag in tasks.tags if tag.id == 3 %}    
    the id is 3
    {% if tag.name == 'blue' %}
    the id of the tag is 3 and tag.name is blue
    {% else %} 
    the id of the tag is 3 but the tag.name is not blue
    {% endif %}
{% else %}
    there was no tag.id 3 found in the tasks.tags
{% endfor %}

LIVE example

现场例子

TWIG documentation

TWIG文档

#4


1  

I found myself the solution. Didn't expect it to be so simple. Sometimes I guess I just try to make things too complicated.

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

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

In my opinion this is not the most efficient way but it does the trick for me at the moment.

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

Edit

编辑

Yenne Info tipped me about the following method. It's a bit cleaner. I don't know if it improves performance though.

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

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

#5


1  

Setting Flag in Twig

{% set flag = 0 %}

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

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

Creating a Custom Filter in PHP

To reduce the code in your templates twig has the opportunity to create custom filters. To achieve a more general functionality you can simply use variable variable names and use the attribute name as another parameter.

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

PHP

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);

Twig

枝条

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

#6


1  

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

Context

If you are going to do conditions on an arbitrary deep array, why not using the power of xpath? An array is no more than an unserialized XML string after all!

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

So, the following array:

那么,以下数组:

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

Is the equivalent of the XML string (fixed to avoid numeric tags):

是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>

And you want to know if your array matches the following xpath expression:

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

//tags/*[id=20]

Implementation

We create a new twig Test that will convert our array into a SimpleXMLElement object, and use SimpleXMLElement::xpath() to check if a given xpath matches.

我们创建了一个新的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);
});

We are now able to run the following test in Twig:

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

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

Full executable implementation:

完整可执行实现:

xpath_test.php

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://*.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);

To run it

运行它

composer require twig/twig
php xpath_test.php

#1


5  

Set a flag and use a loop. Afterwards you can use the flag in if conditions.

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

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

#2


4  

this one is more like a multidimensional loop in case it's necessary

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

   {% for animals in array %}

        {% set dogs = animals.dogs %}

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

    {% endfor %}

#3


2  

For an if-statement within a multi-dimensional array in Twig. Check within the for-loop and then the if statement.

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

Here is the shorthand for this with Twig:

以下是Twig的简写:

{% for tag in tasks.tags if tag.id == '20' %}      
       here_if_true
{% endfor %}    

---- EDIT ----

----编辑----

FOR ELSE

对于ELSE

To do an else. So the else here is if nothing is found in the entire for:

做别的。所以这里的其他内容是,如果在整个过程中找不到任何内容:

{% for tag in tasks.tags %}    
       here_if_true
{% else %}
       if there was nothing found
{% endfor %}    

FOR-IF ELSE

FOR-IF ELSE

Making a combination of the if and else is possible, but it is NOT the same as an if else inside the for loop. Because the else is for the for and not for the if.

组合if和else是可能的,但它与for循环中的if else不同。因为else是for for而不是if。

{% 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

现场例子

FOR-IF ELSE and IF ELSE

FOR-IF ELSE和IF ELSE

{% for tag in tasks.tags if tag.id == 3 %}    
    the id is 3
    {% if tag.name == 'blue' %}
    the id of the tag is 3 and tag.name is blue
    {% else %} 
    the id of the tag is 3 but the tag.name is not blue
    {% endif %}
{% else %}
    there was no tag.id 3 found in the tasks.tags
{% endfor %}

LIVE example

现场例子

TWIG documentation

TWIG文档

#4


1  

I found myself the solution. Didn't expect it to be so simple. Sometimes I guess I just try to make things too complicated.

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

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

In my opinion this is not the most efficient way but it does the trick for me at the moment.

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

Edit

编辑

Yenne Info tipped me about the following method. It's a bit cleaner. I don't know if it improves performance though.

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

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

#5


1  

Setting Flag in Twig

{% set flag = 0 %}

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

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

Creating a Custom Filter in PHP

To reduce the code in your templates twig has the opportunity to create custom filters. To achieve a more general functionality you can simply use variable variable names and use the attribute name as another parameter.

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

PHP

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);

Twig

枝条

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

#6


1  

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

Context

If you are going to do conditions on an arbitrary deep array, why not using the power of xpath? An array is no more than an unserialized XML string after all!

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

So, the following array:

那么,以下数组:

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

Is the equivalent of the XML string (fixed to avoid numeric tags):

是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>

And you want to know if your array matches the following xpath expression:

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

//tags/*[id=20]

Implementation

We create a new twig Test that will convert our array into a SimpleXMLElement object, and use SimpleXMLElement::xpath() to check if a given xpath matches.

我们创建了一个新的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);
});

We are now able to run the following test in Twig:

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

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

Full executable implementation:

完整可执行实现:

xpath_test.php

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://*.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);

To run it

运行它

composer require twig/twig
php xpath_test.php