在PHP中使用多个键值查找进行数组过滤

时间:2010-08-23 22:13:21

标签: php arrays wordpress

我正在使用wordpress插件进行高级表单设计/逻辑/处理,其中一个(最大的)缺点是它提供表单数据的尴尬方式。数据以数组形式给出,每个字段包含两个或三个项目。

如果是隐藏字段:

  1. $$$n => id - 其中n是表单中字段的顺序,NAME是名称/ ID。
  2. id => value - 其中id是名称/ ID,值是值。
  3. 如果是可见字段:

    1. $$$n => LABEL - 其中n是表单中字段的顺序,LABEL是人类可读的标签。
    2. $$$id => LABEL - 其中id是字段的名称/ ID
    3. LABEL => value - 价值是我真正想要的。
    4. 我正在尝试编写一个消耗这个可怕数组的函数,并返回一个更简单的函数,每个字段都有一个id => value对。

      例如,它将采用此方法(无法保证字段的顺序):

      array(
          '$$$1' => 'command',
          'command' => 'signup',
          '$$$2' => 'First Name',
          '$$$firstname' => 'First Name',
          'First Name' => 'John',
          '$$$3' => 'Email Address',
          '$$$email' => 'Email Address',
          'Email Address' => 'john@example.com'
      );
      

      返回:

      array(
          'command' => 'signup',
          'email' => 'john@example.com',
          'firstname' => 'John'
      );
      

      此代码有效,但感觉非常尴尬。你能帮助改进它吗?谢谢! (我的策略是忽略除$$$n字段之外的所有字段,因为它们对于所有表单都是相同的,并且没有简单的方法来判断给定字段是否隐藏。)

      function get_cforms_data($cformsdata) {
      $data = array();
      foreach ($cformsdata as $key => $value) {
          if (strpos($key, '$$$') === 0) {
              $newkey = substr($key, 3);
              if (is_numeric($newkey)) {
                  $keys = array_keys($cformsdata, $value);
                  if (count($keys) == 1) {
                      // must be a hidden field - NAME only appears once
                      $data[$value] = $cformsdata[$value];
                  } else {
                      // non-hidden field.  Isolate id.
                      foreach($keys as $k) {
                          if ($k == $key) {
                              // $$$n - ignore it
                              continue;
                          } else {
                              // $$$id
                              $k = substr($k, 3);
                              $data[$k] = $cformsdata[$value];
                          }
                      }
                  }
              }
          }
      }
      return $data;
      }
      

2 个答案:

答案 0 :(得分:2)

这是一个有效的版本:

$i=0;
$result = array();

while (array_key_exists('$$$' . ++$i, $arr)) {
    $key = $arr['$$$' . $i];
    $result[$key] = $arr[$key];
}

它将打印:

Array
(
    [command] => signup
    [First Name] => John
    [Email Address] => john@example.com
)

这是另一个版本。它更加丑陋但完全符合您的要求(正如我所解释的那样)

function get_cforms_data($cformsdata) {
    $i=0;
    $result = array();
    $flipped = array_flip($arr);

    while (array_key_exists('$$$' . ++$i, $arr)) {
        $key = $arr['$$$' . $i];

        $realKey = (!preg_match('~^\${3}\d+$~', $flipped[$key])) ? 
                    substr($flipped[$key], 3) : $key;

        $result[$realKey] = $arr[$key];
    } 
    return $result;   
}

返回:

Array
(
    [command] => signup
    [firstname] => John
    [email] => john@example.com
)

看到它正常工作:http://ideone.com/5mkbx

答案 1 :(得分:0)

这是我可能会做的,虽然我不认为它比你的更清洁或NullUserException:

function get_cforms_data($cforms_data) {
    $ret = array();
    $label_to_id = array();
    $label_or_id_to_value = array();
    foreach ($cforms_data as $key => $value) {
        if (substr($key, 0, 3) === "$$$") {
            if (!is_numeric($id = substr($key, 3))) {
                $label_to_id[$value] = $id;
            }
        } else {
            $label_or_id_to_value[$key] = $value;
        }
    }
    foreach ($label_or_id_to_value as $key => $value) {
        $ret[isset($label_to_id[$key]) ? $label_to_id[$key] : $key] = $value;
    }
    return $ret;
}