pineapple1 Posted April 25, 2009 Share Posted April 25, 2009 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! Quote Link to comment https://forums.phpfreaks.com/topic/155573-grouping-array-rows/ Share on other sites More sharing options...
RussellReal Posted April 25, 2009 Share Posted April 25, 2009 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.. Quote Link to comment https://forums.phpfreaks.com/topic/155573-grouping-array-rows/#findComment-818741 Share on other sites More sharing options...
pineapple1 Posted April 25, 2009 Author Share Posted April 25, 2009 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. Quote Link to comment https://forums.phpfreaks.com/topic/155573-grouping-array-rows/#findComment-818742 Share on other sites More sharing options...
.josh Posted April 25, 2009 Share Posted April 25, 2009 Serial # Color Width Height Weight 16 Blue 15mm 25mm 50kg 23 Blue 15mm 25mm 50kg 42 Blue 15mm 25mm 50kg so...which column decides whether something is in the same group or not? do all of columns have to match? Any of them? One or more? Quote Link to comment https://forums.phpfreaks.com/topic/155573-grouping-array-rows/#findComment-818744 Share on other sites More sharing options...
pineapple1 Posted April 25, 2009 Author Share Posted April 25, 2009 In order to be same group, they'd have to be the exact same piece of glass. So all columns would have to match - except the serial # Quote Link to comment https://forums.phpfreaks.com/topic/155573-grouping-array-rows/#findComment-818745 Share on other sites More sharing options...
mikesta707 Posted April 25, 2009 Share Posted April 25, 2009 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 Quote Link to comment https://forums.phpfreaks.com/topic/155573-grouping-array-rows/#findComment-818748 Share on other sites More sharing options...
pineapple1 Posted April 25, 2009 Author Share Posted April 25, 2009 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. Quote Link to comment https://forums.phpfreaks.com/topic/155573-grouping-array-rows/#findComment-818753 Share on other sites More sharing options...
.josh Posted April 25, 2009 Share Posted April 25, 2009 $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); Quote Link to comment https://forums.phpfreaks.com/topic/155573-grouping-array-rows/#findComment-818755 Share on other sites More sharing options...
pineapple1 Posted April 25, 2009 Author Share Posted April 25, 2009 Hmmm.. that's giving me an error "argument 1 is not an array" for $diff = array_diff($row,$prev); Quote Link to comment https://forums.phpfreaks.com/topic/155573-grouping-array-rows/#findComment-818758 Share on other sites More sharing options...
.josh Posted April 25, 2009 Share Posted April 25, 2009 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); Quote Link to comment https://forums.phpfreaks.com/topic/155573-grouping-array-rows/#findComment-818761 Share on other sites More sharing options...
pineapple1 Posted April 25, 2009 Author Share Posted April 25, 2009 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); } Quote Link to comment https://forums.phpfreaks.com/topic/155573-grouping-array-rows/#findComment-818763 Share on other sites More sharing options...
.josh Posted April 25, 2009 Share Posted April 25, 2009 Are you putting my code inside the while loop or after it? Quote Link to comment https://forums.phpfreaks.com/topic/155573-grouping-array-rows/#findComment-818766 Share on other sites More sharing options...
pineapple1 Posted April 25, 2009 Author Share Posted April 25, 2009 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. Quote Link to comment https://forums.phpfreaks.com/topic/155573-grouping-array-rows/#findComment-818767 Share on other sites More sharing options...
.josh Posted April 25, 2009 Share Posted April 25, 2009 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) Quote Link to comment https://forums.phpfreaks.com/topic/155573-grouping-array-rows/#findComment-818769 Share on other sites More sharing options...
pineapple1 Posted April 25, 2009 Author Share Posted April 25, 2009 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); } ?> Quote Link to comment https://forums.phpfreaks.com/topic/155573-grouping-array-rows/#findComment-819212 Share on other sites More sharing options...
.josh Posted April 25, 2009 Share Posted April 25, 2009 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. Quote Link to comment https://forums.phpfreaks.com/topic/155573-grouping-array-rows/#findComment-819257 Share on other sites More sharing options...
pineapple1 Posted April 27, 2009 Author Share Posted April 27, 2009 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 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 Quote Link to comment https://forums.phpfreaks.com/topic/155573-grouping-array-rows/#findComment-820561 Share on other sites More sharing options...
pineapple1 Posted April 29, 2009 Author Share Posted April 29, 2009 Still stuck Any suggestions? Quote Link to comment https://forums.phpfreaks.com/topic/155573-grouping-array-rows/#findComment-821732 Share on other sites More sharing options...
pineapple1 Posted April 29, 2009 Author Share Posted April 29, 2009 Anybody have any thoughts? What's wrong with my array.....? The code works fine when using Crayon Violet's array. Quote Link to comment https://forums.phpfreaks.com/topic/155573-grouping-array-rows/#findComment-822021 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.