3

I have a $string:

'Name   Height  Weight
 John   177     142
 Jill   156     123
 Jacob  183     157'

And I'm turning it into an $array of the following structure:

Array (
    [0] => Array (
        ['Name'] => 'John'
        ['Height'] => '177'
        ['Weight'] => '142'
    )
    [1] = > Array (
        ['Name'] => 'Jill'
        ['Height'] => '156'
        ['Weight'] => '123'
    )
    [2] = > Array (
        ['Name'] => 'Jacob'
        ['Height'] => '183'
        ['Weight'] => '157'
    )
)

Using the following code:

$rows = explode("\n",$string); //creates an indexed array of rows as strings
$headers = explode("\t",$rows[0]); //creates an indexed array of headers as strings
$rows = array_slice($rows,1); //removes headers from $rows
$array = Array();
foreach($rows as $row) {
    $array[] = array_combine($headers, explode("\t",$row)); //creates associative arrays for each row
}

However, I cannot access the associative arrays inside of the indexed $array

For example, this doesn't work:

echo $array[0]['Name'];

Even though echo implode(', ', array_keys($array[0])); gives:

Name, Height, Weight

I've tried many different ways of accessing the associative arrays inside of the indexed array, but with no luck. What am I doing wrong?

EDIT:

So,

$string = "Name Height  Weight
John    177 142
Jill    156 123
Jacob‌​ 183 157";

Does not work, but

$string = "Name\tHeight\tWeight\nJohn\t177\t142\nJill\t156\t123\nJacob‌​‌​\t183\t157";

does...

So I suppose the question is: What's the difference? And how would I interpret the former string as the latter?

11
  • Did you print_r($array)? What do you see? Commented Mar 15, 2017 at 6:53
  • Ermm nope, the array your code produces does not have that format Commented Mar 15, 2017 at 6:54
  • @u_mulder Yes, I see the array structure mentioned above (excluding the single quotes) Commented Mar 15, 2017 at 6:55
  • @HankyPanky How come that structure is what print_r() and var_dump() show? Commented Mar 15, 2017 at 6:56
  • 1
    3v4l.org/NhXGD works fine with tabs as delimiters. Make sure that delimiters in your string are tabs. Commented Mar 15, 2017 at 7:00

2 Answers 2

1

Your code does not produce that array structure but it can be fixed like this:

$string = 'Name   Height  Weight
 John   177     142
 Jill   156     123
 Jacob  183     157';

$rows = explode("\n",$string); //creates an indexed array of rows as strings

$headers = preg_split("#\s+#",trim($rows[0], "\n\r\t ")); //creates an indexed array of headers as strings, by splitting by any white space
var_dump($headers);

$rows = array_slice($rows,1); //removes headers from $rows
$array = Array();
foreach($rows as $row) {
    $array[] = array_combine($headers, preg_split("#\s+#",trim($row, "\n\r\t "))); //creates associative arrays for each row, by splitting by any white space
}

var_dump($array);

This produces output:

array(3) {
  [0]=>
  string(4) "Name"
  [1]=>
  string(6) "Height"
  [2]=>
  string(6) "Weight"
}
array(3) {
  [0]=>
  array(3) {
    ["Name"]=>
    string(4) "John"
    ["Height"]=>
    string(3) "177"
    ["Weight"]=>
    string(3) "142"
  }
  [1]=>
  array(3) {
    ["Name"]=>
    string(4) "Jill"
    ["Height"]=>
    string(3) "156"
    ["Weight"]=>
    string(3) "123"
  }
  [2]=>
  array(3) {
    ["Name"]=>
    string(5) "Jacob"
    ["Height"]=>
    string(3) "183"
    ["Weight"]=>
    string(3) "157"
  }
}

The main ideas are that you must trim evey row string by any additional whitespaces and to split by the longest whitespace sequence.

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

6 Comments

Thank you. Give me a minute to wrap my head around this. In the meantime, any idea why print_r(), var_dump(), and implode(', ', array_keys($array[0])) are all suggesting that the array structure is correct?
Okay, any reason why preg_split() is a better alternative to explode()? Unfortunately the real keys I'm using have spaces in them, so this won't work for me :/
I chose regular expression split because the input string can vary. If it does not vary, and always have the exact same structure (i.e. only one TAB character) then is not a better alternative in your case.
Okay. Unfortunately, I need to use the tabs as the delimiters since the keys have spaces in them.
Then your code should work. I also have tested with tabs as other says and it worked. Try with this input string: $string = "Name\tHeight\tWeight\nJohn\t177\t142\nJill\t156\t123\nJacob\t183\t157";
|
0
//Use following code it will work as your answer 
$string='Name   Height  Weight
 John   177     142
 Jill   156     123
 Jacob  183     157';

 $rows = explode("\n",$string); //creates an indexed array of rows as strings

$headers = explode("\t",$rows[0]); //creates an indexed array of headers as strings

$headers=array_filter(explode(" ",$headers[0])); ///t convert to space and filter remove empty element

$rows = array_slice($rows,1); //removes headers from $rows

$array = Array();
foreach($rows as $row) {
    $row=explode("\t",$row);
    $row=array_filter(explode(" ",$row[0]));

    $array[] = array_combine($headers,$row); //creates associative arrays for each row
}

//print_r($array);
echo $array[0]['Name'];

3 Comments

Thank you. Now, what if I want spaces in my array keys? For example: "Person's Name" instead of "Name"
If you want to use that type of the header ["Person's Name"] then the logic is wrong from the start. We need to use diffrent logic for that explode \n will give you space separate string in single row.
Okay, thanks. It seems my problem is not having \t in the string, but I'm not sure how to "replace" tabs with \t, if that makes sense... See the edit to my question.

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.