【问题标题】:PHP: How do I compare values in nested associative arrays?PHP:如何比较嵌套关联数组中的值?
【发布时间】:2018-02-26 03:12:04
【问题描述】:

我正在努力思考如何做到这一点……

我有一个类似的东西:

$contributors = array(
[0] => array(
    [name] => 'John',
    [role] => 'author',
    ),
[1] => array(
    [name] => 'Gail',
    [role] => 'author',
    ),
[2] => array(
    [name] => 'Beth',
    [role] => 'illustrator',
    ),
)

我正在尝试使用这些信息来构建详细的署名,例如:

由约翰和盖尔撰写。由贝丝设计。

我需要将每个 role 与上一个和下一个进行比较,以便:

  1. 在每个role 的第一个实例之前使用标签
  2. 用逗号分隔同一role 的多个实例
  3. 在每个role 的最后一个实例之前使用“and”而不是逗号

我不是 PHP 专家,所以我很难弄清楚如何解决这个问题!我有一个函数可以根据role 输出正确的标签,但这是我似乎无法弄清楚的比较。我考虑过foreachwhile 循环,但似乎都不能胜任这项工作。我从未使用过for 循环,所以我不知道它是否适用。

一些额外的背景:

  • 我正在使用 WordPress 和高级自定义字段插件。
  • $contributorsACF Repeater 字段的值,其中 namerole 是子字段。 (我已经简化了名称以使事情变得更容易。)

【问题讨论】:

  • 你只有两个角色,作者和插画家吗?

标签: php wordpress compare associative-array advanced-custom-fields


【解决方案1】:

您可以按角色对数组进行分组,并使用array_pop 删除元素。 implode 剩余的数组元素,只需附加 弹出值

$contributors = array(
    array(
        "name" => 'John',
        "role" => 'author',
        ),
    array(
        "name" => 'Gail',
        "role" => 'author',
        ),
    array(
        "name" => 'Jose',
        "role" => 'author',
        ),
    array(
        "name" => 'Thomas',
        "role" => 'author',
        ),
    array(
        "name" => 'Beth',
        "role" => 'illustrator',
        ),
    array(
        "name" => 'Mary',
        "role" => 'producer',
        ),
    array(
        "name" => 'Criss',
        "role" => 'producer',
        ),
);

//Grouped the names according to role
$grouped = array_reduce($contributors, function($c, $v) {
    if ( !isset( $c[ $v['role'] ] ) ) $c[ $v['role'] ] = array();
    $c[ $v['role'] ][] = $v['name'];
    return $c;
}, array());


//Construct final Array
$final = array();
foreach( $grouped as $key => $group ) {
    $last = array_pop( $group );

    if ( count( $group ) == 0 ) $final[ $key ] = $last; /* One one name on the role, no need to do anything*/
    else $final[ $key ] = implode( ", ", $group ) . " and " . $last;
}

echo "<pre>";
print_r( $final );
echo "</pre>";

这将导致:

Array
(
    [author] => John, Gail, Jose and Thomas
    [illustrator] => Beth
    [producer] => Mary and Criss
)

您现在可以将其用作

echo 'Written by ' . $final["author"] . '. Designed by ' . $final["illustrator"] . '. Produced by ' . $final["producer"];

结果是:

由约翰、盖尔、何塞和托马斯撰写。由贝丝设计。由。。。生产 玛丽和克里斯

【讨论】:

  • 这太完美了,谢谢!相当简单(尽管我必须查看 array_reduce 才能了解发生了什么),并且我能够对其进行修改以用于更复杂的用途。
【解决方案2】:

你可以这样尝试-

$contributors = array(
  array(
    'name' => 'John',
    'role' => 'author',
  ),
  array(
    'name' => 'Gail',
    'role' => 'author',
  ),
  array(
    'name' => 'Ali',
    'role' => 'author',
  ),
  array(
    'name' => 'Beth',
    'role' => 'illustrator',
  )
);

#This function prepare array to expected String
function PrepareArray($data){
  $combined = '';
  if (count($data)>1) {
    $last       = array_slice($data, -1);
    $first      = join(', ', array_slice($data, 0, -1));
    $both       = array_filter(array_merge(array($first), $last), 'strlen');
    $combined   = join(' and ', $both);
  }else{
    $combined = implode('', $data);
  }
  return $combined;
}

$authors    = array();
$designers  = array();

foreach ($contributors as $key => $value) {
  if ($value['role']=='author') {
    $authors[]      = $value['name'];        #Keep Authors name in Array
  }else if ($value['role']=='illustrator') {
    $designers[]    = $value['name'];            #Keep Designers name in Array
  }
}

$authors    = PrepareArray($authors);
$designers  = PrepareArray($designers);

echo "Written by {$authors}. Designed by {$designers}.";

输出:

由约翰、盖尔和阿里撰写。由贝丝设计。

【讨论】:

    【解决方案3】:

    试试下面的代码:

    <?php
    
    $contributors = array(
      0 => array(
        'name' => 'John',
        'role' => 'author',
      ),
      1 => array(
        'name' => 'Gail',
        'role' => 'author',
      ),
      2 => array(
        'name' => 'Beth',
        'role' => 'illustrator',
     ),
     3 => array(
        'name' => 'Albert',
        'role' => 'author',
     ),
    );
    
    
    $labels = ['author'=>'Written by', 'illustrator'=>'Designed by', 'producer'=>'Produced by'];
    
    $new_contributors = [];
    
    foreach($contributors as $cont){
        $new_contributors[$cont['role']][] = $cont['name'];
    }
    $str = '';
    foreach($labels as $role=>$label){
      if(isset($new_contributors[$role]) && is_array($new_contributors[$role])){
        $str .= ' '.$label.' ';
        foreach($new_contributors[$role] as $key=>$new_contributor){
            $count = count($new_contributors[$role]);
            if(($count - $key) == 1 ){
                $str .= ' and ';
                $str .= $new_contributor;
            }else if(($count - $key) == 2){
                $str .= $new_contributor;
            }else{
                $str .= $new_contributor.', ';
            }
        }
      }
    
    }
    
    echo $str;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-10-24
      • 1970-01-01
      • 2013-10-22
      • 2012-05-03
      • 1970-01-01
      • 2015-06-24
      • 1970-01-01
      相关资源
      最近更新 更多