views:

328

answers:

3

I have an app that shows store sales. It is a multi-dimensional array, so each value in the root array is an array containing [sales], [cost], [date], etc. for the given day it pertains to. OK, there are 2 arrays for each store. One is for verified numbers and the next is for unverified numbers. The unverified picks up right after the verified, so the first date in unverified will be one day after the verified.

OK, all this is fine so far.

But when I show the total sales for all stores, I need to combine all the verified and all the unverified numbers to get the total. Here's the tricky part. The verified array should only go up to the date of the lowest verified store and all the rest should be unverified. For example: On a given date, if all the stores have verified numbers but one is unverified for that date, then they all need to be unverified for that date. So it's like it needs to create a verified total, and an unverified total, check each array and if they are all verified add to the verified array, else if any are unverified add to unverified array.

I hope this makes since, I am trying my best to explain the situation. I do have an algorithm that is working but it's so complex I have to study it forever every time I work on it, and I was hoping there was a more elegant solution.

Thanks!!!

Here is what the array structure looks like

$verified ( 
 [0](sales => 355, cost=> 233, date=> 2008-03-01)
 [0](sales => 235, cost=> 133, date=> 2008-03-02)
 [0](sales => 435, cost=> 143, date=> 2008-03-02)
)
$unverified ( 
     [0](sales => 232, cost=> 133, date=> 2008-03-03)
     [0](sales => 335, cost=> 233, date=> 2008-03-04)
     [0](sales => 535, cost=> 243, date=> 2008-03-05)
    )

This is dummy data, but in reality there will be more entries. There are these 2 arrays for each store. The date won't show up for both arrays; a date will only be in unverified or verified.

But when you have several sets of these arrays for each store and need to combine them, different store's unverified numbers will begin at different dates. storeA may be verified up to the 15th and storeB may be verified up to the 7th. So I need to build a new $verified and a new $unverified from all the ones for each store. But I can't simply combine all the verifieds, because they span across different date ranges. So if all the dates are verified then they stay verified in the new master array, but if any are unverified they need to go to the new master unverified array.

If this doesn't make since I am sorry.

+2  A: 

Much more often, strategic breakthrough will come from redoing the representation of the data or tables. This is where the heart of a program lies. Show me your flowcharts and conceal your tables, and I shall continue to be mystified. Show me your tables, and I won't usually need your flowcharts; they'll be obvious.

—Frederick P. Brooks, Jr., The Mythical Man-Month

I assume that you'd like to construct $total_verified and $total_unverified arrays for all stores.

  1. Construct $total_unverified from $unverified arrays for all stores keeping track of the earliest date in $earliest_unverified_date.

  2. Add value from each $verified array for all stores to $total_verified iff the record has date and it is earlier than $earliest_unverified_date else add the value to $total_unverified array.

J.F. Sebastian
+1  A: 

Your problem sounds like the sort of thing relational databases were made for. Are you using a database? If so, a proper query (or two queries) using GROUP BY or ROLLUP could save you a bazillion lines of PHP.

Nathan
+1: if the data were in one database it would be the job for SQL.
J.F. Sebastian
+1  A: 

I assume you are pulling all these numbers from a database (and if not, why not?), and that your database looks something like

TABLE SalesSummary

Id   StoreId  Date        SalesTotal  CostTotal  Verified
...
231  1        2008-03-01  355.00      233.00     true
232  2        2008-03-01  299.00      233.00     true
233  1        2008-03-02  235.00      133.00     false
234  2        2008-03-02  335.00      133.00     true
235  1        2008-03-03  435.00      143.00     false
236  2        2008-03-03  319.00      143.00     false

then

SELECT MIN(Date) AS FirstUnverifiedDate FROM SalesSummary WHERE Verified=false

finds the first unverified date, and

SELECT
  (Date < $FirstUnverifiedDate) AS Verified,
  StoreId,
  SUM(SalesTotal) AS SalesSum,
  SUM(CostTotal) AS CostSum
FROM
  SalesSummary
WHERE
  Date >= $BeginningOfMonth
GROUP BY
  (Date < $FirstUnverifiedDate) DESC,
  StoreId ASC

gets you the sales totals you wanted - without having to pull the full dataset from the database every time!

Hugh Bothwell