FUDforum
Fast Uncompromising Discussions. FUDforum will get your users talking.

Home » Imported messages » comp.lang.php » Using += assignment recursively on an array w/o notice
Show: Today's Messages :: Polls :: Message Navigator
Switch to threaded view of this topic Create a new topic Submit Reply
Using += assignment recursively on an array w/o notice [message #179437] Sun, 28 October 2012 17:21 Go to next message
Scott Johnson is currently offline  Scott Johnson
Messages: 196
Registered: January 2012
Karma: 0
Senior Member
Hello

I am pulling data from a DB that represent products and product options.


<ProductName>
<Color>
<Size>
<Qty>

The same Product name will represent several rows of color/size
combinations with a qty amount.

What I would like to be able to do is walk thru the returned data set
returned and aggregate the qty from all the rows into a an array for
later processing.

what I tried was this:

$item = array();
foreach($products as $data) {
$item[$data['ProductName']]['TotalQty'] += $data['Qty'];
$item[$data['ProductName']]['data'] = $data;
}

Now this does work and gives me the exact data I need in the right schema.

The problem I am running into is I am getting a Notice about undefined
index since the first iteration of the += is looking for an array index
yet to be declared.

Now I figured a statement that works

$item[$data['ProductName']]['TotalQty'] =
isset($item[$data['ProductName']]['TotalQty']) ?
$item[$data['ProductName']]['TotalQty'] + $data['Qty'] : $data['Qty'];


Is there a statement that will give me something simpler then this or is
this just the way to do it.

Just curious.

Thanks
Scotty
Re: Using += assignment recursively on an array w/o notice [message #179439 is a reply to message #179437] Sun, 28 October 2012 20:09 Go to previous messageGo to next message
Thomas 'PointedEars'  is currently offline  Thomas 'PointedEars'
Messages: 701
Registered: October 2010
Karma: 0
Senior Member
Scott Johnson wrote:

> I am pulling data from a DB that represent products and product options.
>
> <ProductName>
> <Color>
> <Size>
> <Qty>
>
> The same Product name will represent several rows of color/size
> combinations with a qty amount.
>
> What I would like to be able to do is walk thru the returned data set
> returned and aggregate the qty from all the rows into a an array for
> later processing.
>
> what I tried was this:
>
> $item = array();
> foreach($products as $data) {
> $item[$data['ProductName']]['TotalQty'] += $data['Qty'];
> $item[$data['ProductName']]['data'] = $data;

If this occurs more often, I would consider using references for easier
maintenance:

$product_name = $data['ProductName'];
$item[$product_name] = array();
$a =& $item[$product_name];
$a['TotalQty'] += $data['Qty'];
$a['data'] = $data;

(However, consecutive execution of the last statement (optimized or not)
does not make sense. The `data' item of the array would always contain only
the data in the last record for the product.)

This also goes a long way towards avoiding the notice:

> }
>
> Now this does work and gives me the exact data I need in the right schema.

Are you sure about that?

> The problem I am running into is I am getting a Notice about undefined
> index since the first iteration of the += is looking for an array index
> yet to be declared.
>
> Now I figured a statement that works
>
> $item[$data['ProductName']]['TotalQty'] =
> isset($item[$data['ProductName']]['TotalQty']) ?
> $item[$data['ProductName']]['TotalQty'] + $data['Qty'] : $data['Qty'];

(Yuck. Are you sure you would know why you did this in a month from now?
Would you want to read that in other's code?)

$product_name = $data['ProductName'];

if (!array_key_exists($product_name, $item))
{
$item[$product_name] = array(
'TotalQty' => 0,
'data' => $data,
);

$a =& $item[$product_name];
}

$a['TotalQty'] += $data['Qty'];

(You could skip the reference definition here. And decide for either
lowercase or uppercase keys.) Untested.

> Is there a statement that will give me something simpler then this or is
> this just the way to do it.

First of all, ask yourself why you have to care about notices. They are
good for development but should be hidden in production, even from log
files, so as not to make a junk file.

Second, you can define what messages you see:

/* Disable notices */
error_reporting(error_reporting() ^ E_NOTICE);

$item[$data['ProductName']]['TotalQty'] += $data['Qty'];

/* Enable notices */
error_reporting(error_reporting() | E_NOTICE);

Third, you can suppress all notices, warnings and non-fatal errors that a
statement generates, with the `@' notation:

@$item[$data['ProductName']]['TotalQty'] += $data['Qty'];

Works for me. But I have found `@' to cause a syntax error with language
constructs like `echo' (@echo), and often you do not want warnings right-
hand side of an assignment suppressed. So be careful with that.

Fourth, using the same feature, you can make these assignments part of a
function – say, foo() – and call that function with

@foo();

to suppress all notices, warnings and non-fatal errors it would generate.
Because of that, you should limit the function body to the parts that you
actually want to be silent.

That said, I strongly suggest proper coding instead of suppressing notices.
They are there for a reason.


PointedEars
--
Danny Goodman's books are out of date and teach practices that are
positively harmful for cross-browser scripting.
-- Richard Cornford, cljs, <cife6q$253$1$8300dec7(at)news(dot)demon(dot)co(dot)uk> (2004)
Re: Using += assignment recursively on an array w/o notice [message #179440 is a reply to message #179437] Sun, 28 October 2012 21:37 Go to previous messageGo to next message
Denis McMahon is currently offline  Denis McMahon
Messages: 634
Registered: September 2010
Karma: 0
Senior Member
On Sun, 28 Oct 2012 10:21:51 -0700, Scott Johnson wrote:

> $item = array();
> foreach($products as $data) {
> $item[$data['ProductName']]['TotalQty'] += $data['Qty'];
> $item[$data['ProductName']]['data'] = $data;
> }
>
> Now this does work and gives me the exact data I need in the right
> schema.
>
> The problem I am running into is I am getting a Notice about undefined
> index since the first iteration of the += is looking for an array index
> yet to be declared.
>
> Now I figured a statement that works
>
> $item[$data['ProductName']]['TotalQty'] =
> isset($item[$data['ProductName']]['TotalQty']) ?
> $item[$data['ProductName']]['TotalQty'] + $data['Qty'] : $data['Qty'];
>
> Is there a statement that will give me something simpler then this or is
> this just the way to do it.

$item = array();
foreach($products as $data) {
if ( !isset( $item[$data['ProductName']] ) ) {
$item[$data['ProductName']] = array();
$item[$data['ProductName']]['TotalQty'] = 0;
}
$item[$data['ProductName']]['TotalQty'] += $data['Qty'];
$item[$data['ProductName']]['data'] = $data;
}

However, I see a possible issue in your initial loop and my modified
version!

Given that you may have multiple $data with the same ['ProductName'],
what value ends up in:

$item[$data['ProductName']]['data']

because I think it gets over-written every time you find another product
that matched the product name, in which case, why are you bothering to
collect it at all? For each 'ProductName' it will simply contain the last
found "<ProductName> <Color> <Size> <Qty>" array for the last found
$products[] that matched that ProductName!

Consider:

Widget red large 7
Widget blue huge 8
Widget green large 5
Widget yellow medium 6
widget purple small 3
widget green tiny 4
widget yellow huge 2

Your final values for $item['widget'] would I think look like this:

$item['widget']['TotalQty'] = 35
$item['widget']['data'] = array( "widget", "yellow", "huge", 2 );

Perhaps you actually want something more like:

$item = array();
foreach($products as $data) {
if ( !isset( $item[$data['ProductName']] ) ) {
$item[$data['ProductName']] = array();
$item[$data['ProductName']]['TotalQty'] = 0;
$item[$data['ProductName']]['data'] = array();
}
$item[$data['ProductName']]['TotalQty'] += $data['Qty'];
$item[$data['ProductName']]['data'][] = array( $data['Color'],
$data['Size'], $data['Qty'] );
}

Where for each ProductName:

$item[$data['ProductName']]['TotalQty'] => Total Qty
$item[$data['ProductName']]['data'] => array of individual color / size /
qty info

Giving eg:

$item['widget']['TotalQty'] = 35
$item['widget']['data'][0] = array( "red", "large", 7 );
$item['widget']['data'][1] = array( "blue", "huge", 8 );
$item['widget']['data'][2] = array( "green", "large", 5 );
$item['widget']['data'][3] = array( "yellow", "medium", 6 );
$item['widget']['data'][4] = array( "purple", "small", 3 );
$item['widget']['data'][5] = array( "green", "tiny", 4 );
$item['widget']['data'][6] = array( "yellow", "huge", 2 );

Rgds

Denis McMahon

(untested code)
Re: Using += assignment recursively on an array w/o notice [message #179586 is a reply to message #179439] Sun, 11 November 2012 14:32 Go to previous message
Curtis Dyer is currently offline  Curtis Dyer
Messages: 34
Registered: January 2011
Karma: 0
Member
Thomas 'PointedEars' Lahn <PointedEars(at)web(dot)de> wrote:

> Scott Johnson wrote:
>
>> I am pulling data from a DB that represent products and product
>> options.

<snip>

>> $item[$data['ProductName']]['TotalQty'] =
>> isset($item[$data['ProductName']]['TotalQty']) ?
>> $item[$data['ProductName']]['TotalQty'] + $data['Qty'] :
>> $data['Qty'];

<snip>

>> Is there a statement that will give me something simpler then
>> this or is this just the way to do it.
>
> First of all, ask yourself why you have to care about notices.
> They are good for development but should be hidden in
> production, even from log files, so as not to make a junk file.
>
> Second, you can define what messages you see:
>
> /* Disable notices */
> error_reporting(error_reporting() ^ E_NOTICE);

Just a small note for those who might use this code in contexts in
which PHP's error reporting is already set to ignore notices: this
code would actually enable notices (where permission to do so
allows).

If you want code to disable notices in an idempotent fashion, try
instead:

error_reporting(error_reporting() & ~E_NOTICE);

<snip>


@OP: more info on the error reporting function:
<http://php.net/error_reporting>

--
Curtis Dyer
<?$x='<?$x=%c%s%c;printf($x,39,$x,39);?>';printf($x,39,$x,39);?>
  Switch to threaded view of this topic Create a new topic Submit Reply
Previous Topic: Problem with mysqli_stmt_bind_param()
Next Topic: Message queues not working properly PHP -> C
Goto Forum:
  

-=] Back to Top [=-
[ Syndicate this forum (XML) ] [ RSS ]

Current Time: Thu Nov 28 03:53:35 GMT 2024

Total time taken to generate the page: 0.02942 seconds