Reputation: 6471
I am parsing a text file that looks more or less like this:
123.animal=cat
123.name=fred
123.food=fish
345.animal=dog
petshop=zoonoria
This is how I am parsing it:
$file_path = $filename;
$linesArray = file($file_path);
$properties = array();
foreach ($linesArray AS $line) {
if (strlen($line) && $line[0] == '#') {
$pdate = substr($line, 1);
$date = rtrim($pdate);
$formatted = DateTime::createFromFormat('* M d H:i:s T Y',$date);
}
if (false !== ($pos = strpos($line, '='))) {
$prop=array();
$prop[trim(substr($line, 0, $pos))] = trim(substr($line, $pos + 1));
$lineContArray = explode("=", $line);
$identArray = explode(".", $lineContArray[0]);
$ident = $identArray[0];
$type = $identArray[1];
$value = trim($lineContArray[1]);
$found = 0;
for ($i=0; $i<count($properties); $i++) {
if ($properties['number'] == $ident) {
$properties[$i][$type]= $value;
$found=1;
break;
}
}
if ($found == 0) {
if (!empty($type)) {
$properties[] = array('number' => $ident, $type => $value);
} else {
$properties[] = array($ident => $value); }
}
}
My result is:
array(3) {
[0]=>
array(2) {
["number"]=>
string(3) "123"
["animal"]=>
string(3) "cat"
}
[1]=>
array(2) {
["number"]=>
string(3) "123"
["name"]=>
string(4) "fred"
}
[3]=>
array(2) {
["number"]=>
string(3) "345"
["animal"]=>
string(4) "dog"
}
[4]=>
array(1) {
["petshop"]=>
string(5) "zoonoria"
}
}
But I need the array to be different, this is the result I like to achieve:
array(3) {
[123]=>
array(3) {
["animal"]=>
string(3) "cat"
["name"]=>
string(4) "fred"
["food"]=>
string(4) "fish"
}
[345]=>
array(1) {
["animal"]=>
string(3) "dog"
}
[petshop]=>
string(8) "zoonoria"
}
}
So my main problem is, I do not know how to turn number
into the key. I tried various things, but I failed. I am really happy for every hint.
I tried the solution of Svetlio:
$file_path = $filename;
$linesArray = file($file_path);
$properties = array();
foreach ( $linesArray as $str) {
$exp = explode ('=', $str);
if(count($exp) == 2){
$exp2 = explode('.', $exp[0]);
if( count($exp2) == 2 ) {
$properties [$exp2[0]][$exp2[1]] = $exp[1];
} else {
$properties [$exp[0]] = $exp[1];
}
} else {
}
}
My result:
array(3) {
["123"]=>
array(3) {
["animal"]=>
string(3) "cat
"
["name"]=>
string(4) "fred
"
["food"]=>
string(4) "fish
"
}
[345]=>
array(1) {
["animal"]=>
string(3) "dog
"
}
["petshop"]=>
string(3) "zoonoria
"
}
Upvotes: 1
Views: 85
Reputation: 212412
$data = '123.animal=cat
123.name=fred
123.food=fish
345.animal=dog
petshop=zoonoria';
$ini = parse_ini_string($data);
$result = [];
foreach ($ini as $key => $value) {
$splitKey = explode('.', $key);
$iniPtr = &$result;
foreach($splitKey as $subKey) {
if (!isset($iniPtr[$subKey])) { $iniPtr[$subKey] = null; }
$iniPtr = &$iniPtr[$subKey];
}
$iniPtr = $value;
}
unset($iniPtr);
var_dump($result);
In your case, use $ini = parse_ini_file($file_path);
to read your file data into $ini
Upvotes: 1
Reputation:
foreach ($linesArray AS $line) {
if (strlen($line) && $line[0] == '#') {
$pdate = substr($line, 1);
$date = rtrim($pdate);
$formatted = DateTime::createFromFormat('* M d H:i:s T Y',$date);
}
if (false !== ($pos = strpos($line, '='))) {
$prop=array();
$prop[trim(substr($line, 0, $pos))] = trim(substr($line, $pos + 1));
$lineContArray = explode("=", $line);
$identArray = explode(".", $lineContArray[0]);
$ident = $identArray[0];
$type = $identArray[1];
$value = trim($lineContArray[1]);
$found = 0;
for ($i=0; $i<count($properties); $i++) {
if ($properties['number'] == $ident) {
$properties[$i][$type]= $value;
$found=1;
break;
}
}
if ($found) {
if ($type && $ident) {
$properties[$ident][$type] = $value;
} else if (!$type && $ident) {
$properties[$ident][] = $value;
}else if ($type && !$ident){
$properties[$type][] = $value;
}
}
Upvotes: 1
Reputation: 24276
After getting the result you can use array_reduce to get the desired result
$result = array_reduce($initialArray, function ($result, $item) {
$number = isset($item['number']) ? $item['number'] : end(array_keys($result));
if (!isset($result[$number])) {
$result[$number] = array();
}
foreach ($item as $key => $value) {
if ($key == 'number') continue;
$result[$number][$key] = $value;
}
return $result;
}, array());
Upvotes: 1
Reputation: 4686
Here is working solution but it doesn't cover the cases where stings don't contain = or have more than 1 of them..
$strings = array(
'123.animal=cat',
'123.name=fred',
'123.food=fish',
'345.animal=dog',
'petshop=zoonoria'
);
$array = array();
foreach ( $strings as $str) {
// I accept that there is 1 = at strings possible
$exp = explode ('=', $str);
if(count($exp) == 2){
$exp2 = explode('.', $exp[0]);
if( count($exp2) == 2 ) {
$array[$exp2[0]][$exp2[1]] = $exp[1];
} else {
// if there are multiple/null dots i set the string as key
$array[$exp[0]] = $exp[1];
}
} else {
// what to do if there are no or many = = = in the string ?
}
}
var_dump($array);
Upvotes: 2