Advertisement:

Author Topic: How to combine arrays?  (Read 2172 times)

Offline Study Force

  • SMF Hero
  • ******
  • Posts: 3,310
    • StudyForcePS on Facebook
    • @studyforceps on Twitter
    • Study Force
How to combine arrays?
« 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
Code: [Select]
fgetcsv() to extract the rows, that part is done!

When I execute the while statement:

while( ($row fgetcsv($handle4096,","'"' )) !== FALSE 
{
	
	

	
print_r($row);
}


I get:

Code: [Select]

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:

Code: [Select]

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($handle4096,","'"' )) !== FALSE 
{
	
	

	
echo 
$row[0] . $row[1];
}


I only get two outputs instead of the original 4.

Offline Sesquipedalian

  • The Mad Doctor
  • Lead Developer
  • Jr. Member
  • *
  • Posts: 323
  • Gender: Male
  • It works! ... in theory.
    • Sesquipedalian on GitHub
Re: How to combine arrays?
« Reply #1 on: February 17, 2018, 05:13:16 AM »
If /tmp/test.csv contains the following:
Code: [Select]
"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($handle4096,","'"' )) !== 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:
Code: [Select]
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.
« Last Edit: February 17, 2018, 05:27:44 AM by Sesquipedalian »
I promise you nothing.

Sesqu... Sesqui... what?
Sesquipedalian, the best word in the English language.

Offline Study Force

  • SMF Hero
  • ******
  • Posts: 3,310
    • StudyForcePS on Facebook
    • @studyforceps on Twitter
    • Study Force
Re: How to combine arrays?
« Reply #2 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?
« Last Edit: February 17, 2018, 11:34:46 AM by Study Force »

Offline Sesquipedalian

  • The Mad Doctor
  • Lead Developer
  • Jr. Member
  • *
  • Posts: 323
  • Gender: Male
  • It works! ... in theory.
    • Sesquipedalian on GitHub
Re: How to combine arrays?
« Reply #3 on: February 18, 2018, 12:16:46 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($handle4096,","'"' )) !== 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:
Code: [Select]
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
)
I promise you nothing.

Sesqu... Sesqui... what?
Sesquipedalian, the best word in the English language.

Offline Study Force

  • SMF Hero
  • ******
  • Posts: 3,310
    • StudyForcePS on Facebook
    • @studyforceps on Twitter
    • Study Force
Re: How to combine arrays?
« Reply #4 on: February 18, 2018, 01:03:03 AM »
What an awesome script you helped me create. It works flawlessly.

Thank you!

Offline Sesquipedalian

  • The Mad Doctor
  • Lead Developer
  • Jr. Member
  • *
  • Posts: 323
  • Gender: Male
  • It works! ... in theory.
    • Sesquipedalian on GitHub
Re: How to combine arrays?
« Reply #5 on: February 18, 2018, 08:39:28 PM »
You're welcome. :)
I promise you nothing.

Sesqu... Sesqui... what?
Sesquipedalian, the best word in the English language.

Offline Study Force

  • SMF Hero
  • ******
  • Posts: 3,310
    • StudyForcePS on Facebook
    • @studyforceps on Twitter
    • Study Force
Re: How to combine arrays?
« Reply #6 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?

Code: [Select]
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
)

Offline Sesquipedalian

  • The Mad Doctor
  • Lead Developer
  • Jr. Member
  • *
  • Posts: 323
  • Gender: Male
  • It works! ... in theory.
    • Sesquipedalian on GitHub
Re: How to combine arrays?
« Reply #7 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($handle4096,","'"' )) !== 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:
Code: [Select]
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($handle4096,","'"' )) !== 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:
Code: [Select]
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
)
I promise you nothing.

Sesqu... Sesqui... what?
Sesquipedalian, the best word in the English language.

Offline Study Force

  • SMF Hero
  • ******
  • Posts: 3,310
    • StudyForcePS on Facebook
    • @studyforceps on Twitter
    • Study Force
Re: How to combine arrays?
« Reply #8 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?

Offline Sesquipedalian

  • The Mad Doctor
  • Lead Developer
  • Jr. Member
  • *
  • Posts: 323
  • Gender: Male
  • It works! ... in theory.
    • Sesquipedalian on GitHub
Re: How to combine arrays?
« Reply #9 on: February 21, 2018, 12:27:15 AM »
How can we get the count to restart inside every new array?

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($handle4096,","'"' )) !== 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:
Code: [Select]
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
)
I promise you nothing.

Sesqu... Sesqui... what?
Sesquipedalian, the best word in the English language.

Offline Study Force

  • SMF Hero
  • ******
  • Posts: 3,310
    • StudyForcePS on Facebook
    • @studyforceps on Twitter
    • Study Force
Re: How to combine arrays?
« Reply #10 on: February 21, 2018, 11:07:16 AM »
Perfect. ^^

Offline Sesquipedalian

  • The Mad Doctor
  • Lead Developer
  • Jr. Member
  • *
  • Posts: 323
  • Gender: Male
  • It works! ... in theory.
    • Sesquipedalian on GitHub
Re: How to combine arrays?
« Reply #11 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($handle4096,","'"' )) !== 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:
Code: [Select]
"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:
Code: [Select]
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.
I promise you nothing.

Sesqu... Sesqui... what?
Sesquipedalian, the best word in the English language.

Offline Study Force

  • SMF Hero
  • ******
  • Posts: 3,310
    • StudyForcePS on Facebook
    • @studyforceps on Twitter
    • Study Force
Re: How to combine arrays?
« Reply #12 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?

Offline Sesquipedalian

  • The Mad Doctor
  • Lead Developer
  • Jr. Member
  • *
  • Posts: 323
  • Gender: Male
  • It works! ... in theory.
    • Sesquipedalian on GitHub
Re: How to combine arrays?
« Reply #13 on: February 22, 2018, 08:42:49 PM »
What if I want a random $concat_num each time between 1 and 10?

Replace the 3 with mt_rand(1, 10).

I promise you nothing.

Sesqu... Sesqui... what?
Sesquipedalian, the best word in the English language.

Offline Study Force

  • SMF Hero
  • ******
  • Posts: 3,310
    • StudyForcePS on Facebook
    • @studyforceps on Twitter
    • Study Force
Re: How to combine arrays?
« Reply #14 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.

Offline Sesquipedalian

  • The Mad Doctor
  • Lead Developer
  • Jr. Member
  • *
  • Posts: 323
  • Gender: Male
  • It works! ... in theory.
    • Sesquipedalian on GitHub
Re: How to combine arrays?
« Reply #15 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.
I promise you nothing.

Sesqu... Sesqui... what?
Sesquipedalian, the best word in the English language.

Offline Study Force

  • SMF Hero
  • ******
  • Posts: 3,310
    • StudyForcePS on Facebook
    • @studyforceps on Twitter
    • Study Force
Re: How to combine arrays?
« Reply #16 on: February 23, 2018, 12:38:05 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

Offline Study Force

  • SMF Hero
  • ******
  • Posts: 3,310
    • StudyForcePS on Facebook
    • @studyforceps on Twitter
    • Study Force
Re: How to combine arrays?
« Reply #17 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) {

Offline Study Force

  • SMF Hero
  • ******
  • Posts: 3,310
    • StudyForcePS on Facebook
    • @studyforceps on Twitter
    • Study Force
Re: How to combine arrays?
« Reply #18 on: February 23, 2018, 10:41:26 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.
« Last Edit: February 23, 2018, 11:32:11 PM by Study Force »

Offline Sesquipedalian

  • The Mad Doctor
  • Lead Developer
  • Jr. Member
  • *
  • Posts: 323
  • Gender: Male
  • It works! ... in theory.
    • Sesquipedalian on GitHub
Re: How to combine arrays?
« Reply #19 on: February 25, 2018, 12:31:33 AM »
Glad you got it sorted out. :)
I promise you nothing.

Sesqu... Sesqui... what?
Sesquipedalian, the best word in the English language.