Jump to content

Grouping Array Rows


pineapple1

Recommended Posts

My situation is this.. I've got a multidimensional array where I'd like to group common rows and output them as a single row with a qty.  Even if that quantity is just 1.

 

Currently, my code groups the rows together by using multisort, but I have no idea how to consolidate them into a single row and qty.

 

For example: 

 

Serial #

Color

Width

Height

Weight

16

Blue

15mm

25mm

50kg

23

Blue

15mm

25mm

50kg

42

Blue

15mm

25mm

50kg

 

Would become

Qty

Serial #'s

Color

Width

Height

Weight

3

16,23,42

Blue

15mm

25mm

50kg

 

Does that make sense?

 

I just have no clue how best to tackle this.  Right now my data is structured as a multidimensional array... $data[row][col].

 

Any advice would be very much appreciated!

Link to comment
Share on other sites

ok, based on this, just because 2 items are the same specsdoesn't mean they are the same item.. don't group them at all is my opinion.. if they order 12 of the same serial number, then group them, otherwise, thats veryweird to see you buying qty 3 of 3 different items.. and could get confusing on ur end also..

Link to comment
Share on other sites

Well, this isn't for an inventory program or anything. Actually, you could replace Serial # with Label # or Name. They are for stickers that will go on a whole bunch of glass pieces for installation in a building. That "serial" corresponds to a specific location on the facade of the building.  But I want to be able to tell the glass manufacturer what the common sizes are to make it easier to fabricate.

Link to comment
Share on other sites

So i assume you just want to group the information about this array into a different array?

ok well after you get some information about the arrays you can just make some functions to do what you want to do with the arrays.

ok so the array you want till be something like this

$data_simplified = array('serial'=> , 'color =>,...etc);

 

for the quantity

just do something like

function quantity($array){
$i = 0;
foreach ($array as $array){
$++
}

would that work to get your quantity?

for the color, you could just assign the first value of your data array to the color, and pretty much do the same for the rest of columns. You could also test if they were different if you wanted to really, and change the array based on that.

 

but yeah, the function above would give you the quantity (I think) so getting the other values shouldnt be too hard to figure out

Link to comment
Share on other sites

Thanks for the code.  What you are suggesting for the QTY would work.  However, without anyway of isolating the groups, wouldn't this function just give me the number of rows of data in the entire table?  In my example, I only show a few rows but we're talking about a couple hundred sizes - maybe 30 different common ones.  I think the trick to all this is determining how to group them.  That's where I'm lost.

Link to comment
Share on other sites

$prev = array();
$current = 0;
// $array is your current multidim array
foreach ($array as $row) {
   $diff = array_diff($row,$prev);
   unset($diff['serial']);
   if (count($diff) == 0) {
      $newList[$current]['serial'] .= ',' . $row['serial'];
   } else {
      $current++;
      $newList[$current] = $row;
   }
   $prev = $row;
}
echo "<pre>"; print_r($newList);

Link to comment
Share on other sites

well are you using your real multi-dim array instead of $array in the foreach? Here is same code with example $array...

 

<?php
$array[] = array('serial'=>16,'color'=>'blue','width'=>'15mm','height'=>'25mm','weight'=>'50kg');
$array[] = array('serial'=>23,'color'=>'blue','width'=>'15mm','height'=>'25mm','weight'=>'50kg');
$array[] = array('serial'=>42,'color'=>'blue','width'=>'15mm','height'=>'25mm','weight'=>'50kg');
$array[] = array('serial'=>16,'color'=>'red','width'=>'15mm','height'=>'25mm','weight'=>'50kg');
$array[] = array('serial'=>16,'color'=>'red','width'=>'15mm','height'=>'25mm','weight'=>'50kg');

$prev = array();
$current = 0;
// $array is your current multidim array
foreach ($array as $row) {
   $diff = array_diff($row,$prev);
   unset($diff['serial']);
   if (count($diff) == 0) {
      $newList[$current]['serial'] .= ',' . $row['serial'];
   } else {
      $current++;
      $newList[$current] = $row;
   }
   $prev = $row;
}
echo "<pre>"; print_r($newList);

Link to comment
Share on other sites

Wow. Works fine using your array. I did change the variable to suit my array. Perhaps it has to do with how I'm reading in the data. I'm using fgetcsv to read in a csv file.

 

$i=-1;

$file=fopen('glass.csv','r') or die("Can't open file");

while(!feof($file)){

$i++;

$data[$i]=fgetcsv($file,1024);

}

Link to comment
Share on other sites

Nah... Here's the full code - I've been messing around with it so it might look a little different now:

 

<?php

//Open and read CSV file
$file=fopen('glass.csv','r') or die("Can't open file");
$data=fgetcsv($file,1024);

$prev = array();
$current = 0;
foreach ($data as $row) {
   $diff = array_diff($row,$prev);
   unset($diff['serial']);
   if (count($diff) == 0) {
      $newList[$current]['serial'] .= ',' . $row['serial'];
   } else {
      $current++;
      $newList[$current] = $row;
   }
   $prev = $row;
}
echo "<pre>"; print_r($newList);
?>

 

 

I get 3 warnings, all in reference to the array_diff.  Then my output looks like this:

 

Array

(

    [0] => Array

        (

            [serial] => ,2,7,1

        )

 

)

 

 

I'm wondering if maybe it is because some of the fields of the CSV are blank.  There is still a placeholder for them, but they are blank.  For example...    16,red,43mm,,45kg.

Link to comment
Share on other sites

What happened to the rest of your file reading part? What you have in that posted code only reads the first line. You need that while loop and that $i++ etc.. to create your multi-dim array when you are reading the file.  And it doesn't look you changed $array to $data in the foreach argument.

 

foreach($data as $row)

 

 

Link to comment
Share on other sites

Sorry, I was messing around with it trying to get it to work.  No luck.  I take it I have to have the while loop like I originally had it right?  Does your code go inside that loop then? Like it is here:

 

<?php
$i=-1;
$file=fopen('glass.csv','r') or die("Can't open file");
while(!feof($file)){
$i++;
$array[$i]=fgetcsv($file,1024);

//CRAYON VIOLET CODE.
$prev = array();
$current = 0;
// $array is your current multidim array
foreach ($array as $row) {
   $diff = array_diff($row,$prev);
   unset($diff['serial']);
   if (count($diff) == 0) {
      $newList[$current]['serial'] .= ',' . $row['serial'];
   } else {
      $current++;
      $newList[$current] = $row;
   }
   $prev = $row;
}
echo "<pre>"; print_r($newList);

}
?>

Link to comment
Share on other sites

I wrote the code assuming you already had a multi-dim array, because that's what you said.  So my code has to come after the while loop, after the multi-dim array is already generated.  If you have it inside the while loop like that, You are just dealing with $array as a single-dim array, which is causing $row to not be a 2nd level array, but individual elements of data.  Therefore you end up getting the array_diff error. 

 

If you want to have that stuff inside the while loop, then you need to get rid of the foreach loop and use $array instead of $row in the array_diff (and everywhere else that uses $row).

 

Also, I'm just going to preemptively throw this out there...you originally said you already had your multi-dim array sorted a certain way before, and was then wanting to group the serial numbers.  Well my code assumes that it IS sorted as you said.  So if you are reading these lines from your file, if they are not already sorted in the file that way, it's not going to work the way you want it.

Link to comment
Share on other sites

Thank you for working through this with me.  My PHP skills need a lot of work... but I'm getting there.  I've taken everything you've said into consideration and I think I should have something that works.. but it doesn't  :P  The code still works great when I use your array.  So I know it must be something with mine.  But I can't figure out what?!?!  Here is the code as it stands today:

<?php

//Open and read CSV file example has four columns

$i=-1;
$file=fopen('testdata.csv','r') or die("Can't open file");
while(!feof($file)){
$i++;
$data[$i]=fgetcsv($file,1024);
$data[$i]= array('serial'=>$data[$i][0], 
	'type'=>$data[$i][1],
	'width1'=>$data[$i][2],
	'height1'=>$data[$i][3]);
}

//Make columns sortable for each sortable column
foreach ($data as $key => $row) {
   $serial[$key]  = $row[0];
   $type[$key] = $row[1];
   $width1[$key] = $row[2];
   $height1[$key] = $row[3];
}

array_multisort($type, $width1, $height1, $data);


$prev = array();
$current = 0;
foreach ($data as $row) {
   $diff = array_diff($row,$prev);
   unset($diff['serial']);
   if (count($diff) == 0) {
      $newList[$current]['serial'] .= ',' . $row['serial'];
   } else {
      $current++;
      $newList[$current] = $row;
   }
   $prev = $row;
}

echo "<pre>"; print_r($newList);


?>

The output looks like this:

Array

(

    [1] => Array

        (

            [serial] => 2F-01-A

            [type] => 3

            [width1] => 731

            [height1] => 1975

        )

 

    [2] => Array

        (

            [serial] => 2F-02-A

            [type] => 2

            [width1] => 291

            [height1] => 2153

        )

 

    [3] => Array

        (

            [serial] => 2F-03-A

            [type] => 4

            [width1] => 987

            [height1] => 1556

        )

 

    [4] => Array

        (

            [serial] => 2F-04-A

            [type] => 1

            [width1] => 1076

            [height1] => 2457

        )

 

    [5] => Array

        (

            [serial] => 2F-04-B

            [type] => 1

            [width1] => 1076

            [height1] => 285

        )

 

    [6] => Array

        (

            [serial] => 2F-05-A

            [type] => 1

            [width1] => 1076

            [height1] => 2457

        )

As you can see, keys 4 and 6 should be grouped together, but they're not.  I've also noticed that my multi_sort is not working right.  I think this is probably the key to the problem.  I must be doing this wrong :(
Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.