2015-11-25 6 views
1

Я разбор текстового файла, который выглядит более или менее, как это:Как преобразовать значение массива в ключ массива?

123.animal=cat 
123.name=fred 
123.food=fish 
345.animal=dog 
petshop=zoonoria 

Это как я разбор его:

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

мой результат:

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" 
    } 
} 

Но Мне нужно, чтобы массив был другим, это результат, который мне нравится:

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" 
     } 
    } 

Так что моя главная проблема в том, что я не знаю, как превратить number в ключ. Я пробовал разные вещи, но я потерпел неудачу. Я очень рад за каждый намек.


Я попробовал решение 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 { 

     } 

} 

Мой результат:

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 
" 
} 
+1

Чтобы исправить Ответ Svetlio, измените '$ linesArray = file ($ file_path);' на '$ linesArray = файл ($ file_path, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); ' –

+0

@Mark Baker Спасибо! – Jarla

ответ

2

Здесь работает решение, но оно не распространяется на случаи, когда укусы не содержат = или имеют более 1 из них.

$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); 
+0

Это, кажется, работает очень хорошо, я опубликовал результат вашего решения в моем вопросе. Мне просто интересно, почему '=' находится в следующей строке? – Jarla

+1

rtrim ($ str, "\ n"); (в первой строке внутри foreach) должен удалить новый символ строки, который у вас есть в каждой строке. – Svetoslav

+0

Большое спасибо – Jarla

1

После получения результата вы можете использовать array_reduce, чтобы получить желаемый результат

$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()); 
+0

Я видел это ... Тем временем Я обновил свой ответ. Как я понял, если в элементе нет числового ключа, он будет добавлен к последнему элементу результата. –

1
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; 
      } 

    } 
+0

Хотя этот фрагмент кода может решить вопрос, [включая объяснение] (http://meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers) из кода действительно помогает улучшить качество вашего поста. Помните, что вы отвечаете на вопрос читателей в будущем, и эти люди могут не знать причин вашего предложения кода. Также попробуйте не толковать код с пояснительными комментариями, что уменьшает читаемость кода и объяснений! – Rizier123

+0

Спасибо. Я обязательно отвечу на ваше предложение –

1
$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

В вашем случае, используйте $ini = parse_ini_file($file_path); читать данные файла в $ini

+0

Спасибо, я проверил ваш код (также на новой странице php только ваш код, ничего больше), но мой результат - это страница blanc.Это странно, потому что вы опубликовали рабочую демонстрацию. Поэтому я уверен, что сделал что-то не так. Просто хочу опубликовать вопрос – Jarla

+1

@Jarla - какая версия PHP вы используете? Потому что я использовал синтаксис коротких массивов для '$ result = [];', который требует PHP> = 5.4.0 .... если вы используете меньше, чем это (помимо рекомендации по обновлению до поддерживаемой версии), вам нужно будет use '$ result = array();' –

+0

Я запущен 5.3 – Jarla

Смежные вопросы