tags:

views:

348

answers:

3

I am using PHP. I need to implement the following logic:

My $List has the following data:

array('id' =>'1','flag'=>'1','place1' =>'val2' ,'place2'=>'val3')
array('id'=> '1','flag'=>'0','place1' =>'val3' ,'place2'=>'val7')
array('id'=> '1','flag'=>'0','place1' =>'val4' ,'place2'=>'val8')
array('id'=> '1','flag'=>'0','place1' =>'val5' ,'place2'=>'val9')
array('id'=> '2','flag'=>'1','place1' =>'val10','place2'=>'val11')
array('id'=> '3','flag'=>'1','place1' =>'val11','place2'=>'val14')

My logic:

 if (flag == 0){

        Store the values of place1 ,Place2 
        in the Index of id

       /*example

        $store[1]= {place1}+{place2}
        hence output:

        store[1]= {val3+val4+val5}+{val7+val8+val9}

similarly
        store[2]= empty
        store[3]= empty
         */

    }
   else{
       Print the Values of place1,place2 of its index

       /*    example

    print place1[1]="val2" ,place2[1]='val3'
    place1[2]="val10",place2[2]='val11'
    place1[3]="val11",place2[3]='val14'      
        */
     }

My partial snippet has:

foreach ($List as $key => $val)
{
  if($val['flag']!==0){

   //how to implementation

  }
 else{
     echo '$val['place1']'.'$val['place2']';


  }
}

What is the best way to proceed?

A: 

There is a nice function for filtering data out of an array: array___filter. The function requires a callback function, a function that will make the decision whether an element should stay in the array. We create a filter function using create_function and extract the interesting part of the array.

$reducingFunction = create_function('$value', 'return $value["flag"] == 0;');
$reduced = array_filter($list, $reducingFunction);

The next neat function (array_walk) is one that transforms the elements of our array (i.e. $value = $value['param1']), so we create another callback function:

$extractingFunction = create_function('&$value, $key, $index', '$value = $value[$index];');
$valuesParam1 = $reduced;
$valuesParam2 = $reduced;
array_walk($valuesParam1, $extractingFunction, 'param1');
array_walk($valuesParam2, $extractingFunction, 'param1');

Now we have two arrays containing all the data we need:

$store = array(1 => implode('', $valuesParam1).implode('', $valuesParam2));

I don't seem to understand what you want the array $store to contain else. Or what the else-branch should do, so this would require further explanation.

soulmerge
else Branch Just Sorted Based on Id, and skip if flag ==0
venkatachalam
I think, he explicitely wants the store[id] to be filled with a 0 value, if there is a row with this id, but no row['flag'] == 0. You do filter these ids away before. But actually the question leaves many questions open.
GrGr
Ya ! GrGr Point is Correct ,And also the Store[id] used to extract the data if any time ,since id is 'key' here for place1,place2;
venkatachalam
Ah, now I get it! The id column unifies the arrays involved. Well, the provided answer should give you a good starting point to do the rest yourself. Btw: I'm not using foreach here for performance reasons, the builtin array functions are much faster. You can skip this, if you don't care about that.
soulmerge
Since i am beginner i am hardly analyzing ur code
venkatachalam
If you're trying to improve, you should give it a try - it's not too hard to grasp. Given the amount of questions you asked on SO, you want to learn things, right?
soulmerge
yes Your Words boost me, basically i m like to learn new things!,its only because of tutor like you, I welcome ur suggestion
venkatachalam
Small bug in your Code:Correct one is: $rf=create_function('$value','return $value["flag"] ==0;');
venkatachalam
And also ur $valuesParam1 returns 1,not the array
venkatachalam
soulmerge
+1  A: 

Assumed that you actually have numeric values in place1 and place2 and thus commutative addition is allowed. If you really have text and need the braces, then I would join the two parts with another pass over store later (but then I would not understand the {0}+{0}). I tried to keep your quotation marks in the else part. Not tested at all.

$store = array();
foreach ($List as $key => $val)
{
  $id = $val['id'];
  if (!array_key_exists($id, $store)) {
    $store[$id] = 0;
  }
  if ($val['flag'] == 0) {
    $store[$id] += $val['place1'];
    $store[$id] += $val['place2'];
  } else {
     printf("place1[%d]=\"%s\",place2[%d]='%s'\n", $id, $val['place1'], $id, $val['place2']);
  }
}
GrGr
A: 

The code newbie friendly :

$store = array(); // Don't forget to initialize your vars

foreach ($List as $key => $val)
{

  if ($val['flag']==0)
  {
    // we check if $store[$val['id']] contains any value first and set it to zero
    if (isset($store[$val['id']]))
    {
        // we add the previous value with the new one
        $store[$val['id'] = $store[$val['id']] + $val['place1'] + $val['place2'];
    }
    else
    {
       // first time seeing this id, we set the value to 0
       $store[$val['id']] = 0;
    }

  }
  else
  {
     echo '$val['place1']'.'$val['place2']'."\n"; // adding line break (use </ br> if in a web browser)
  }
}

I didn't get if "flag" should be 0 or not, so tweak it on.

Version 2 :

If "flag" is just used for boolean logic, you'd may just replace the above code with :

if (!$val['flag'])

Then you can use PHP shortcuts to sum up :

$store[$val['id'] += $val['place1'] + $val['place2'];

Bracelets are not required for one line operations :

if (isset($store[$val['id']]))
    $store[$val['id'] = $store[$val['id']] + $val['place1'] + $val['place2'];
else
   $store[$val['id']] = 0;

And you don't need the "$key" var either.

So the code becomes :

$store = array(); 

foreach ($List as $val)

  if (!$val['flag'])
    if (isset($store[$val['id']]))
        $store[$val['id'] += $val['place1'] + $val['place2'];
    else
       $store[$val['id']] = 0;

  else
     echo '$val['place1']'.'$val['place2']'."\n";

Version 3 :

if / else/ set operations can be shorten using the ternary operator (beware it's less readable and slower):

$store[$val['id'] = isset($store[$val['id']]) ? 0 : $store[$val['id']] + $val['place1'] + $val['place2'];

So the code becomes :

$store = array(); 

foreach ($List as $val)
  if (!$val['flag'])
    $store[$val['id'] = isset($store[$val['id']]) ? 0 : $store[$val['id']] + $val['place1'] + $val['place2'];
  else
     echo '$val['place1']'.'$val['place2']'."\n";

Pro version

Once you get this one, check soulmerge's code. It is really smarter to use fonctional programming when you can since it's smaller, and result can be piped to each others, so the code is more reusable. What's more, using generators consume often less memory.

e-satis
Like soulmerge's solution, you will not have $store[$id] set to 0 for ids which have only 1-flags, but the $store[$id] will simply not be set at all. That is why I put the initialization before the if ($val['flag'] == 0) block. You are missing a closing bracket in the $store[$val['id'] = ... lines.
GrGr
I just saw, that you skip the first row for each id with 0-flag, because the store is set to 0 instead of $val['place1'] + $val['place2'].
GrGr