1

I have a text flat file data.txt with data in this specific format and it's always the same:

id: 24153
firstname: john
lastname: smith
registered: true
id: 27663
firstname: ben
lastname: jackson
registered: false

How can I read the text file and loop through all the data points to make a single array with all the data arranged in the following way:

Array
(
    [0] => Array
        (
            [id] => 24153
            [firstname] => john
            [lastname] => smith
            [registered] => 1
        )

    [1] => Array
        (
            [id] => 27663
            [firstname] => ben
            [lastname] => jackson
            [registered] => 
        )

)

My incomplete/failed attempts. I can put it all into a single array but not sure how to format it in the way described.

$lines = file('data.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);

$arr = array();
foreach ($lines as $line_num => $line) {
    if (strpos($line, 'id') !== false) {
        $arr[$line] = //not sure how to move forward from here
    }
}
5
  • 1
    just read the file using fopen and fgets with a simple while loop, and couple it with a few of your if statements checking if the line is an id, firstname, lastname, and registered, if it satisfies then save it inside an array Commented May 8, 2018 at 4:17
  • 3
    anyway, where are the codes? Commented May 8, 2018 at 4:18
  • Just as an FYI, Stack Overflow isn't here to do your programming. We are here to help you if you get stuck on some small part. Commented May 8, 2018 at 4:22
  • 1
    Well, there's file() to read the entire file into an array. From there you might be interested in array_chunk() to break up the array into groups of 4. Then you might want to look at array_map() and array_reduce() for transforming the data. Let us know how you go Commented May 8, 2018 at 4:29
  • For those of you who said i didnt make any attempt.. please dont make assumptions. i did make an attempt but i didnt include it in my original post as it was bad but that's where im stuck. Anyway, i just updated the post to include it. Commented May 8, 2018 at 4:33

4 Answers 4

2

Option 1: If id is always the first line of the group, you can do a simpler approach using just 1 loop.

Using array_values will convert associative array into simple array.

$fh = fopen('newfile.txt','r');
$result = array();
while ($line = fgets($fh)) {
    $line = trim($line);
    if ( $line !== '' ) {
        $line = explode(":", $line, 2);
        if ( trim( $line[0] ) === 'id' ) $id = trim( $line[1] );
        $result[$id][trim( $line[0] )] = trim( $line[1] );
    }
}
fclose($fh);

echo "<pre>";
print_r( array_values($result) );
echo "</pre>";

Option 2: You can use loop thru each line of the file. Chunk the array. And use array_reduce to format the array.

$fh = fopen('newfile.txt','r');                                //Open file
$arr = array();
while ($line = fgets($fh)) {                                   //Loop thru each line
    $arr[] = trim($line);                                      //Trim the line and push in array
}
fclose($fh);

$arr = array_chunk( $arr, 4 );                                  //chunk array in the size of 4

//use array_reduce to format the array Format array
$result = array_reduce($arr, function($c,$v){
    $temp = array();
    $id = "";

    foreach($v as $val) {
        $val = explode(":", $val, 2);
        $temp[ trim( $val[0] ) ] = trim( $val[1] );
    }

    $c[$id] = $temp;
    return $c;
},array());

echo "<pre>";
print_r( $result );
echo "</pre>";

This will result to:

Array
(
    [24153] => Array
        (
            [firstname] => john
            [lastname] => smith
            [registered] => true
        )

    [27663] => Array
        (
            [firstname] => ben
            [lastname] => jackson
            [registered] => false
        )

)
Sign up to request clarification or add additional context in comments.

2 Comments

would it take much to modify the code so each chunk is inside another array 0,1 incrementing numbers rather than that the employee id as the array name? the employee id can be a subkey and value like the rest. I updated my post to include the new format.
@user3436467 I updated my answer based on your new format. I also added a different simpler approach if id is the first line of the group.
1

Simplest approach is using array_chunk(),foreach() and explode()

<?php


$lines = file('data.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);

$chunk_array = array_chunk($lines,4);

$arr = array();
$key = 0;
foreach ($chunk_array as $line_num => $line) {

   foreach($line as $l){
       $exploded_array = explode(':',$l);
       if(trim($exploded_array[0]) =='id'){
           $key = trim($exploded_array[1]);
       }else{
           $arr[$key][trim($exploded_array[0])] = trim($exploded_array[1]);
       }
   }
}
echo "<pre/>";print_r($arr);

Output:- https://prnt.sc/jf3zh5

For your changed requirement do like below:-

<?php


$lines = file('data.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);

$chunk_array = array_chunk($lines,4);

$arr = array();
foreach ($chunk_array as $line_num => $line) {

   foreach($line as $l){
       $exploded_array = explode(':',$l);
       $arr[$line_num][trim($exploded_array[0])] = trim($exploded_array[1]);
   }
}
echo "<pre/>";print_r($arr);

2 Comments

oh cool i could have used line_num without adding $x=0; - noted.
@user3436467 glad to help you :):)
0

Please use this code. This is tested code and working properly as you required. In this script, there is no extra loop required. We are achieved just by the use of if and else.

<?php
if ($file = fopen("file.txt", "r")) {
        $dataArray = array();
        $newline = '';
        $id = '';
    while(!feof($file)) {
        $line = fgets($file);
        # do same stuff with the $line
        if (strpos($line, "id:") !== false) {
            //print_r($line);echo '</br>';
            $id_line = explode(":",$line);
            $id = $id_line[1];
        }else{
            if(!empty($id)){
                $new_line = explode(":",$line);
                $dataArray[$id][$new_line[0]] = $new_line[1];
            }
        }



    }
    fclose($file);
}
echo '<pre>';
print_r($dataArray);
?>

Output:

Array
(
    [ 24153] => Array
        (
            [firstname] =>  john

            [lastname] =>  smith

            [registered] =>  true

        )

    [ 27663] => Array
        (
            [firstname] =>  ben

            [lastname] =>  jackson

            [registered] =>  false
        )

)

1 Comment

@user3436467, Please try this script
0

I will rather do using array_map and array_filter to minimise loop. I have tried with simple string manipulation , you can do it using fopen.

Explanations are included in comments below

$str="id: 24153
firstname: john
lastname: smith
registered: true
id: 27663
firstname: ben
lastname: jackson
registered: false";
//explode by new line
$arr=explode("\n",$str);
//take the value only,OP is saying format is same
$arr1=array_map(function ($a) { return str_replace(":","",strstr($a, ':')); }, $arr);
//remap the value if index is divisible by 4 , that is if it is id, remember the format is fixed
$arr2=array_values(array_filter(array_map(function ($a,$k)use($arr1) { if($k%4==0) { return array($a=>array('firstname'=>$arr1[$k+1],'last_name'=>$arr1[$k+2],'registered'=>$arr1[$k+3]));} else {return null;} }, $arr1,array_keys($arr1))));
echo "<pre>";
print_r($arr2);

output

Array
(
    [0] => Array
        (
            [ 24153] => Array
                (
                    [firstname] =>  john
                    [last_name] =>  smith
                    [registered] =>  true
                )

        )

    [1] => Array
        (
            [ 27663] => Array
                (
                    [firstname] =>  ben
                    [last_name] =>  jackson
                    [registered] =>  false
                )

        )

)

working fiddle: http://phpfiddle.org/main/code/6n5g-bvpx

1 Comment

interesting.. i will take a look at this approach. thank you

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.