Simple Machines Community Forum

General Community => Scripting Help => Topic started by: Biology Forums on February 16, 2018, 11:37:03 AM

Title: How to combine arrays?
Post by: Biology Forums on February 16, 2018, 11:37:03 AM
I have a very specific request. I'll try to make it easy to understand.

Let's pretend we have an Excel file that's 4 rows by 2 columns (in reality it's actually 100's of rows by 2 columns) I'm using fgetcsv() to extract the rows, that part is done!

When I execute the while statement:

while( ($row = fgetcsv($handle, 4096,",", '"' )) !== FALSE )
{
print_r($row);
}

I get:



Array
(
    [0] => blah blah blah
    [1] => he he he
)
Array
(
    [0] => bleh bleh bleh
    [1] => ha ha ha
)
Array
(
    [0] => bloh bloh bloh
    [1] => ho ho ho
)
Array
(
    [0] => bluh bluh bluh
    [1] => hu hu hu
)



I'd like to combine every 2 arrays so that we end up with:



Array
(
    [0] => blah blah blah - - - bleh bleh bleh
    [1] => he he he - - - ha ha ha
)
Array
(
    [0] => bloh bloh bloh - - - bluh bluh bluh
    [1] => ho ho ho - - - hu hu hu
)



So, when I execute the while statement,

while( ($row = fgetcsv($handle, 4096,",", '"' )) !== FALSE )
{
echo $row[0] . $row[1];
}

I only get two outputs instead of the original 4.
Title: Re: How to combine arrays?
Post by: Sesquipedalian on February 17, 2018, 05:13:16 AM
If /tmp/test.csv contains the following:

"blah blah blah","ha ha ha"
"bleh bleh bleh","he he he"
"bloh bloh bloh","ho ho ho"
"bluh bluh bluh","hu hu hu"


then the following code:

$handle = fopen('/tmp/test.csv', 'r');

$tmp = array();
$even = false;
while( ($row = fgetcsv($handle, 4096,",", '"' )) !== FALSE ) {
$tmp[0][] = $row[0];
$tmp[1][] = $row[1];

if ($even) {
$tmp[0] = implode(' - - - ', $tmp[0]);
$tmp[1] = implode(' - - - ', $tmp[1]);
print_r($tmp);
$tmp = array();
}

$even = !$even;
}


produces this output:

Array
(
    [0] => blah blah blah - - - bleh bleh bleh
    [1] => ha ha ha - - - he he he
)
Array
(
    [0] => bloh bloh bloh - - - bluh bluh bluh
    [1] => ho ho ho - - - hu hu hu
)


Note: You didn't specify what you wanted to do with the last line if there was an odd number of lines in the CSV file. This code will not print the last line at all in that case. If that doesn't work for you, you'll need to add something to handle that special case.
Title: Re: How to combine arrays?
Post by: Biology Forums on February 17, 2018, 11:10:34 AM
That's some *very* clever coding, thank you. The last line can be filled in manually, I suppose. It's not ideal, but it's a relatively small thing to worry about.

Since we're on the topic, what if I want to combine 3 rows rather than every 2? Or 4, or 5 rows? Just curious, what would the code be?
Title: Re: How to combine arrays?
Post by: Sesquipedalian on February 18, 2018, 12:16:46 AM
Quote from: Study Force on February 17, 2018, 11:10:34 AM
That's some *very* clever coding, thank you.

You are welcome. :)

Quote
The last line can be filled in manually, I suppose. It's not ideal, but it's a relatively small thing to worry about.

Since we're on the topic, what if I want to combine 3 rows rather than every 2? Or 4, or 5 rows? Just curious, what would the code be?

This version should take care of both requests for you.


$handle = fopen('/tmp/test.csv', 'r');

// Set this to the number of rows you want to concatenate together
$concat_num = 3;

$tmp = array();
$counter = 0;
while( ($row = fgetcsv($handle, 4096,",", '"' )) !== FALSE ) {
$tmp[0][] = $row[0];
$tmp[1][] = $row[1];

if (++$counter === $concat_num) {
$tmp[0] = implode(' - - - ', $tmp[0]);
$tmp[1] = implode(' - - - ', $tmp[1]);
print_r($tmp);

$tmp = array();
$counter = 0;
}
}

// Deal with any leftovers
if (!empty($tmp)) {
$tmp[0] = implode(' - - - ', $tmp[0]);
$tmp[1] = implode(' - - - ', $tmp[1]);
print_r($tmp);
}


Using the same input CSV, this version will output the following:

Array
(
    [0] => blah blah blah - - - bleh bleh bleh - - - bloh bloh bloh
    [1] => ha ha ha - - - he he he - - - ho ho ho
)
Array
(
    [0] => bluh bluh bluh
    [1] => hu hu hu
)
Title: Re: How to combine arrays?
Post by: Biology Forums on February 18, 2018, 01:03:03 AM
What an awesome script you helped me create. It works flawlessly.

Thank you!
Title: Re: How to combine arrays?
Post by: Sesquipedalian on February 18, 2018, 08:39:28 PM
You're welcome. :)
Title: Re: How to combine arrays?
Post by: Biology Forums on February 20, 2018, 08:20:40 PM
I've got one more challenge for you, if you don't mind...

What if I want to number each iteration, like this?


Array
(
    [0] => 1) blah blah blah - - - 2) bleh bleh bleh - - - 3) bloh bloh bloh
    [1] => 1) ha ha ha - - - 2) he he he - - - 3) ho ho ho
)

Title: Re: How to combine arrays?
Post by: Sesquipedalian on February 20, 2018, 09:27:36 PM
You didn't specify whether the numbering should reset back to 1 in every new group or should continue climbing with each subsequent group. Either option is simple, though, so here they both are.

If you want to reset the numbering back to 1 for every new group:

$handle = fopen('/tmp/test.csv', 'r');

// Set this to the number of rows you want to concatenate together
$concat_num = 3;

$tmp = array();
$counter = 0;
while( ($row = fgetcsv($handle, 4096,",", '"' )) !== FALSE ) {
// Increment the counter
++$counter;

$tmp[0][] = $counter . ') ' . $row[0];
$tmp[1][] = $counter . ') ' . $row[1];

if ($counter === $concat_num) {
$tmp[0] = implode(' - - - ', $tmp[0]);
$tmp[1] = implode(' - - - ', $tmp[1]);
print_r($tmp);

$tmp = array();
$counter = 0;
}
}

// Deal with any leftovers
if (!empty($tmp)) {
$tmp[0] = implode(' - - - ', $tmp[0]);
$tmp[1] = implode(' - - - ', $tmp[1]);
print_r($tmp);
}

Result:

Array
(
    [0] => 1) blah blah blah - - - 2) bleh bleh bleh - - - 3) bloh bloh bloh
    [1] => 1) ha ha ha - - - 2) he he he - - - 3) ho ho ho
)
Array
(
    [0] => 1) bluh bluh bluh
    [1] => 1) hu hu hu
)



If you want the numbering in each group to carry on from where the last group left off:

$handle = fopen('/tmp/test.csv', 'r');

// Set this to the number of rows you want to concatenate together
$concat_num = 3;

$tmp = array();
$counter = 0;
$running_total = 0;
while( ($row = fgetcsv($handle, 4096,",", '"' )) !== FALSE ) {
// Increment the counters
++$counter;
++$running_total;

$tmp[0][] = $running_total . ') ' . $row[0];
$tmp[1][] = $running_total . ') ' . $row[1];

if ($counter === $concat_num) {
$tmp[0] = implode(' - - - ', $tmp[0]);
$tmp[1] = implode(' - - - ', $tmp[1]);
print_r($tmp);

$tmp = array();
$counter = 0;
}
}

// Deal with any leftovers
if (!empty($tmp)) {
$tmp[0] = implode(' - - - ', $tmp[0]);
$tmp[1] = implode(' - - - ', $tmp[1]);
print_r($tmp);
}


Result:

Array
(
    [0] => 1) blah blah blah - - - 2) bleh bleh bleh - - - 3) bloh bloh bloh
    [1] => 1) ha ha ha - - - 2) he he he - - - 3) ho ho ho
)
Array
(
    [0] => 4) bluh bluh bluh
    [1] => 4) hu hu hu
)
Title: Re: How to combine arrays?
Post by: Biology Forums on February 20, 2018, 10:04:18 PM
Thank you. One tiny issue.

How can we get the count to restart inside every new array?
Title: Re: How to combine arrays?
Post by: Sesquipedalian on February 21, 2018, 12:27:15 AM
Quote from: Study Force on February 20, 2018, 10:04:18 PM
How can we get the count to restart inside every new array?

Quote from: Sesquipedalian on February 20, 2018, 09:27:36 PM
If you want to reset the numbering back to 1 for every new group:

$handle = fopen('/tmp/test.csv', 'r');

// Set this to the number of rows you want to concatenate together
$concat_num = 3;

$tmp = array();
$counter = 0;
while( ($row = fgetcsv($handle, 4096,",", '"' )) !== FALSE ) {
// Increment the counter
++$counter;

$tmp[0][] = $counter . ') ' . $row[0];
$tmp[1][] = $counter . ') ' . $row[1];

if ($counter === $concat_num) {
$tmp[0] = implode(' - - - ', $tmp[0]);
$tmp[1] = implode(' - - - ', $tmp[1]);
print_r($tmp);

$tmp = array();
$counter = 0;
}
}

// Deal with any leftovers
if (!empty($tmp)) {
$tmp[0] = implode(' - - - ', $tmp[0]);
$tmp[1] = implode(' - - - ', $tmp[1]);
print_r($tmp);
}

Result:

Array
(
    [0] => 1) blah blah blah - - - 2) bleh bleh bleh - - - 3) bloh bloh bloh
    [1] => 1) ha ha ha - - - 2) he he he - - - 3) ho ho ho
)
Array
(
    [0] => 1) bluh bluh bluh
    [1] => 1) hu hu hu
)

Title: Re: How to combine arrays?
Post by: Biology Forums on February 21, 2018, 11:07:16 AM
Perfect. ^^
Title: Re: How to combine arrays?
Post by: Sesquipedalian on February 21, 2018, 01:58:46 PM
:)

By the way, if you need a version that can handle any arbitrary number of columns in your CSV, this would do it:

$handle = fopen('/tmp/test.csv', 'r');

// Set this to the number of rows you want to concatenate together
$concat_num = 3;

$tmp = array();
$counter = 0;
while( ($row = fgetcsv($handle, 4096,",", '"' )) !== FALSE ) {
// Increment the counter
++$counter;

foreach ($row as $column_num => $column_value)
$tmp[$column_num][] = $counter . ') ' . $column_value;

if ($counter === $concat_num) {
foreach ($tmp as $column_num => $column_value)
$tmp[$column_num] = implode(' - - - ', $column_value);

print_r($tmp);

$tmp = array();
$counter = 0;
}
}

// Deal with any leftovers
if (!empty($tmp)) {
foreach ($tmp as $column_num => $column_value)
$tmp[$column_num] = implode(' - - - ', $column_value);

print_r($tmp);
}


Using that code, if test.csv contains this:

"blah blah blah","ha ha ha","la la la","ma ma ma","xa xa xa"
"bleh bleh bleh","he he he","le le le","me me me","xe xe xe"
"blih blih blih","hi hi hi","li li li","mi mi mi","xi xi xi"
"bloh bloh bloh","ho ho ho","lo lo lo","mo mo mo","xo xo xo"
"bluh bluh bluh","hu hu hu","lu lu lu","mu mu mu","xu xu xu"


Then the output will be:

Array
(
    [0] => 1) blah blah blah - - - 2) bleh bleh bleh - - - 3) blih blih blih
    [1] => 1) ha ha ha - - - 2) he he he - - - 3) hi hi hi
    [2] => 1) la la la - - - 2) le le le - - - 3) li li li
    [3] => 1) ma ma ma - - - 2) me me me - - - 3) mi mi mi
    [4] => 1) xa xa xa - - - 2) xe xe xe - - - 3) xi xi xi
)
Array
(
    [0] => 1) bloh bloh bloh - - - 2) bluh bluh bluh
    [1] => 1) ho ho ho - - - 2) hu hu hu
    [2] => 1) lo lo lo - - - 2) lu lu lu
    [3] => 1) mo mo mo - - - 2) mu mu mu
    [4] => 1) xo xo xo - - - 2) xu xu xu
)


I recommend using this final version in your script so that if you need to reuse this code at a later date on a different data set, you won't need to change anything.
Title: Re: How to combine arrays?
Post by: Biology Forums on February 22, 2018, 12:09:49 PM
Actually, I have another request that might challenge you.

What if I want a random $concat_num each time between 1 and 10? For instance, it changes from 2, then 7, then 9, then 10. I'm currently using the code in this post:

https://www.simplemachines.org/community/index.php?topic=558912.msg3962717#msg3962717

Good Lord, did you read my mind with that last post?
Title: Re: How to combine arrays?
Post by: Sesquipedalian on February 22, 2018, 08:42:49 PM
Quote from: Study Force on February 22, 2018, 12:09:49 PM
What if I want a random $concat_num each time between 1 and 10?

Replace the 3 with mt_rand(1, 10).

Title: Re: How to combine arrays?
Post by: Biology Forums on February 22, 2018, 11:25:00 PM
That didn't do it.

Since we've placed $concat_num outside the while statement, it randomizes it at the start, not per array printed. So let's say it decides 4, all arrays are , but I don't want that.
Title: Re: How to combine arrays?
Post by: Sesquipedalian on February 23, 2018, 12:30:06 AM
Oh, I see. Then just change if ($counter === $concat_num) to if ($counter === mt_rand(1, 10)). If you do this, you can delete the $concat_num = 3; line, since $concat_num will no longer be doing anything.
Title: Re: How to combine arrays?
Post by: Biology Forums on February 23, 2018, 12:38:05 AM
Quote from: Sesquipedalian on February 23, 2018, 12:30:06 AM
Oh, I see. Then just change if ($counter === $concat_num) to if ($counter === mt_rand(1, 10)). If you do this, you can delete the $concat_num = 3; line, since $concat_num will no longer be doing anything.

That did it.

ty
Title: Re: How to combine arrays?
Post by: Biology Forums on February 23, 2018, 04:01:41 PM
I'm getting a strange error that I can't figure why it's happening. After a few arrays, it quits and gives me:

PHP Notice:  Undefined offset: 1

For the line:

$tmp[1][] = $counter . ') ' . $row[1];

This only happened after I added:

if ($counter === $concat_num) {
Title: Re: How to combine arrays?
Post by: Biology Forums on February 23, 2018, 10:41:26 PM
Quote from: Study Force on February 23, 2018, 04:01:41 PM
if ($counter === $concat_num) {

Meant to write: $counter === mt_rand(1, 10)

When I changed it to $counter >= mt_rand(1, 10), it works.
Title: Re: How to combine arrays?
Post by: Sesquipedalian on February 25, 2018, 12:31:33 AM
Glad you got it sorted out. :)