Php Изменение последовательного массива на инклюзивный массив
Я работаю над латинским веб-сайтом, который хранит некоторую информацию в строке следующим образом:
nominative:0:us,a,um;genitive:0:i;dative,ablative:1:is
Я хотел бы превратить эту информацию в массив, как это
array(
'nominative'=>array(
0=>array('us','a','um')
),
'genitive'=>array(
0=>'i'
)
'dative'=>array(
1=>'is'
)
'ablative'=>array(
1=>'is'
)
)
Мой текущий код выглядит так
//turn into array for each specification
$specs=explode(';',$specificities);
foreach($specs as $spec):
//turn each specification into a consecutive array
$parts=explode(':',$spec);
//turn multiple value into array
foreach($parts as &$value)
if(strpos($value,',')!==false)
$value=explode(',',$value);
//imbricate into one other
while(count($parts)!==1):
$val=array_pop($parts);
$key=array_pop($parts);
if(is_array($key)):
foreach($key as $k)
$parts[$k]=$val;
else:
$parts[$key]=$val;
endif;
endwhile;
endforeach;
Я застрял. Помогите.
Изменить: Спасибо за быстрые ответы всем! Ответ, который я предпочел, был от CaCtus. Я изменил его, чтобы добавить гибкость, но это было наиболее полезным.
Для тех, кто заинтересован, вот новый код:
$parts=explode(';','nominative:0:er,ra,rum;genitive:0:i;dative,ablative:1:is;root:r;');
if(!empty($parts)&&!empty($parts[0])):
foreach($parts as $part):
$subpart=explode(':',$part);
$keys=explode(',',$subpart[0]);
foreach($keys as $key):
@$vals=(strpos($subpart[2],',')!==false)
?explode(',',$subpart[2])
:$subpart[2];
$final=(is_null($vals))
?$subpart[1]
:array($subpart[1]=>$vals);
endforeach;
endforeach;
endif;
3 ответа
$string = 'nominative:0:us,a,um;genitive:0:i;dative,ablative:1:is';
$finalArray = array();
// Separate each specification
$parts = explode(';', $string);
foreach($parts as $part) {
// Get values : specification name, index and value
$subpart = explode(':', $part);
// Get different specification names
$keys = explode(',', $subpart[0]);
foreach($keys as $key) {
if (preg_match('#,#', $subpart[2])) {
// Several values
$finalValues = explode(',', $subpart[2]);
} else {
// Only one value
$finalValues = $subpart[2];
}
$finalArray[$key] = array(
$subpart[1] => $finalValues
);
}
}
Будет ли что-то немного проще работать?
функция multiexplode ($ delimiters, $ string) {
$ready = str_replace($delimiters, $delimiters[0], $string); $launch = explode($delimiters[0], $ready); return $launch; }
$ input = "0: us, a, um; родительный падеж: 0: i; дательный, аблятивный: 1: is";
$ exploded = multiexplode (array (",", ":", ";"), $ input);
$ test = array ('nominative' => array (0 => array ($ exploded [1], $ exploded [2], $ exploded [3])), $ exploded [4] => array (0 => $ exploded [6]), $ exploded [7] => array (1 => $ exploded [10]), $ exploded [8] => array (1 => $ exploded [10]));
print_r ($ тест);
Просто еще одна альтернатива:
$specificities = "nominative:0:us,a,um;genitive:0:i;dative,ablative:1:is";
$specificities = trim($specificities, ";") . ";"; //mandatory a trailing ;
$pattern = "/(?<types>[a-z\,]+):(?<ids>\d):(?<values>.*?);/";
preg_match_all($pattern, $specificities, $matches, PREG_SET_ORDER);
$result = array();
array_map(function($item) use (&$result)
{
$types = explode("," , $item['types']);
if(count($types) == 1)
{
$result[$item['types']] = array(
$item['ids'] => explode("," , $item['values'])
);
}
else
{
foreach ($types as $type)
{
$result[$type] = array(
$item['ids'] => explode("," , $item['values'])
);
}
}
}, $matches);
var_dump($result);