peace_love
peace_love

Reputation: 6471

How can I turn a value of an array into the key of an array?

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

Answers (4)

Mark Baker
Mark Baker

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);

Demo

In your case, use $ini = parse_ini_file($file_path); to read your file data into $ini

Upvotes: 1

user1562300
user1562300

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

Mihai Matei
Mihai Matei

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

Svetoslav
Svetoslav

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

Related Questions