2

下面是数组结构的示例。我需要能够提取特定值,例如:[245][subfields][a]。每个数组中有可变数量的 [fields] 和可变数量的 [subfields]。感谢您的任何建议!

编辑:我已将数组包含在我正在检索的原生 JSON 格式中。然后我使用 json_decode 将其转换为 php 中的可用数组。如果您有更好的建议,请告诉我。

链接到漂亮的数组

{"leader":"01220nam  2200265   4500","fields":[{"001":"ocm00000197"},{"005":"19880526181046.0"},{"008":"690325r19681924nyua          00000 eng  "},{"010":{"ind1":" ","ind2":" ","subfields":[{"a":"67-020193 \/\/r832"}]}},{"035":{"ind1":" ","ind2":" ","subfields":[{"a":".b10000021"},{"b":"a    "},{"c":"-"}]}},{"041":{"ind1":"1","ind2":" ","subfields":[{"a":"eng"},{"a":"fre"}]}},{"049":{"ind1":" ","ind2":" ","subfields":[{"a":"JBLA"},{"c":"$8.00"}]}},{"100":{"ind1":"1","ind2":"0","subfields":[{"a":"Allemagne, Henry Ren\u00e2e d',"},{"d":"1863-1950."}]}},{"245":{"ind1":"1","ind2":"0","subfields":[{"a":"Decorative antique ironwork :"},{"b":"a pictorial treasury \/"},{"c":"by Henry Ren\u00e2e d'Allemagne ; introd., bibliography, and translation of captions by Vera K. Ostoia."}]}},{"260":{"ind1":"0","ind2":" ","subfields":[{"a":"New York :"},{"b":"Dover Publications,"},{"c":"[1968]"}]}},{"300":{"ind1":" ","ind2":" ","subfields":[{"a":"x, 415 p. :"},{"b":"(chiefly ill.) ;"},{"c":"31 cm."}]}},{"500":{"ind1":" ","ind2":" ","subfields":[{"a":"\"This Dover edition ... is a republication of all the plates in the two portfolios of Mus\u00e2ee Le Secq des Tournelles \u00e1a Rouen: Ferronnerie ancienne, originally published ... in 1924.\""}]}},{"500":{"ind1":" ","ind2":" ","subfields":[{"a":"\"Other books by Henry Ren\u00e2e d'Allemagne\": p. x."}]}},{"590":{"ind1":" ","ind2":" ","subfields":[{"a":"1373336."}]}},{"650":{"ind1":" ","ind2":"0","subfields":[{"a":"Art metal-work."}]}},{"700":{"ind1":"1","ind2":"0","subfields":[{"a":"Ostoia, Vera K."}]}},{"710":{"ind1":"2","ind2":"0","subfields":[{"a":"Mus\u00e2ee Le Secq des Tournelles."}]}},{"830":{"ind1":" ","ind2":"0","subfields":[{"a":"Dover pictorial archive series."}]}},{"999":{"ind1":" ","ind2":" ","subfields":[{"b":"1"},{"c":"901102"},{"d":"m"},{"e":"b"},{"f":"-"},{"g":"0"}]}},{"945":{"ind1":" ","ind2":" ","subfields":[{"a":"739.4\/ALLEMAGNE,H"},{"g":"1"},{"i":"31184001373336"},{"l":"abx7 "},{"n":"moved from RESEARCH collection - Feb 2012"},{"o":"-"},{"p":"$8.00"},{"s":"-"},{"t":"235"},{"u":"10"},{"v":"0"},{"w":"0"},{"x":"1"},{"y":".i10000021"},{"z":"901102"}]}}]}
4

4 回答 4

1

因此,您似乎需要一种方法来遍历fields键以检查其每个子数组的第一个键以匹配您搜索的项目。

// Loop over the fields, which are each arrays numerically indexed...
foreach ($record['fields'] as $key => $field) {
  // Get the field's first array key, which is 010, 015, etc...
  $marc_keys = array_keys($field);
  // the first key...
  $marc_field = $marc_keys[0];
  // Note in PHP 5.4 you could dereference it more easily like
  // $marc_field = array_keys($field)[0];

  // Test if the key you found is the one you want...
  if ($marc_field == '245') {
     foreach ($field[$marc_field]['subfields'] as $subkey => $subfield) {
       // Get the subfield identifier (the first array key)
       $sf_keys = array_keys($subfield);
       $sf_identifier = $sf_keys[0];
       if ($sf_identifier == 'a') {
          // Congratulations Arthur, you found the grail....
          // Do something with it...
       } 
     }
  }
  // Otherwise, keep looping until you find the one you need...
}

作为一个函数:

最好将其转换为接受$field,$subfieldas 参数的函数:

更新以考虑相同类型的多个子字段,并返回一个数组:

function getSubfield($record, $in_field, $in_subfield) {
    // Array to hold output for multiple like subfields
    $subfields_returned = array();

    foreach ($record['fields'] as $key => $field) {
      $marc_keys = array_keys($field);
      $marc_field = $marc_keys[0];

      // Test if the key you found is the one you want (which is the $in_field param)
      if ($marc_field == $in_field) {
         foreach ($field[$marc_field]['subfields'] as $subkey => $subfield) {

           $sf_keys = array_keys($subfield);
           $sf_identifier = $sf_keys[0];

           // And match the subfield to the function param $in_subfield

           if ($sf_identifier == $in_subfield) {
              // Congratulations Arthur, you found the grail....
              // Return it...
              $subfields_returned[] = $subfield[$sf_identifier];
           }
         }
          // After the subfield loop, you can return the accumulated array
         if (count($subfields_returned) > 0) return $subfields_returned;
      }
      // Otherwise, keep looping until you find the one you need...
    }
}

这是一个演示

……我拼凑出一张唱片……

于 2012-12-11T21:12:48.210 回答
1
// behaves like  array(*, 245, *, 'subfields', *, 'a', *);
// where * is a wildcard for 0 or more keys
$keySequence = array(245, 'subfields', 'a');


$arr = array();
$arr[245]['subfields']['a'] = 'i match';
$arr[245]['subfields'][7]['a'] = 'i match';
$arr[0][0][0][245][0][0]['subfields']['subfields'][0]['a']['a'] = 'i match';
$arr[0][0][0][0][0][0]['subfields']['subfields'][0]['a']['a'] = 'i dont match';
$arr[0][0][0][0][0][0]['subfields']['subfields'][0]['a']['a'] = 'i dont match';





$iter = new RecursiveIteratorIterator(new RecursiveArrayIterator($arr));
$filtered = new CallbackFilterIterator($iter, function ($_, $_, $iterator) use ($keySequence) {
    $i = 0;
    $max = count($keySequence);
    foreach (range(0, $iterator->getDepth()) as $depth) {
        if ($keySequence[$i] === $iterator->getSubIterator($depth)->key())
            $i++;
        if ($i === $max)
            return true;
    }
    return $i === $max;
});

foreach ($filtered as $leafVal) {
    echo "$leafVal\n";
}

http://codepad.viper-7.com/9t4qVO

于 2012-12-11T22:09:50.643 回答
0

如果您要对此数据进行大量自定义搜索,您可以考虑使用各种已编写的函数将数组转换为 XML 。然后就可以使用 XPath 灵活的查询数据了。

于 2012-12-11T21:16:51.453 回答
0
function recursiveArrayIterator($arr){
    foreach($arr as $key => $arr2){
        if(is_array($arr2)){
           recursiveArrayIterator($arr2);
        }
    }
}
$arr = array(array('key'=>'value'));
recursiveArrayIterator($arr);

我没有你的要求,但这可能会对你有所帮助。

于 2012-12-11T21:19:05.383 回答