3

I have tried to get the below code to work for a good couple of hours, but just don't succeed.

I have this date array:

Array ( [0] => Array ( [0] => 2007 ) 
        [1] => Array ( [0] => 2008 ) 
        [2] => Array ( [0] => 2009 )
        ...
      )

and this plusMinus one:

Array ( [0] => Array ( [plus] => 2 [date] => 2007 ) 
        [1] => Array ( [minus] => 1 [date] => 2008 ) 
        [2] => Array ( [minus] => 1 [date] => ) 
        [3] => Array ( [plus] => 1 [date] => 2010 [minus] => 1 )
      )

I have been trying to combine them into this:

Array ( [0] => Array ( [date] => 2007 [plus]=> 2)
        [1] => Array ( [date] => 2008 [minus]=> 1)
        [2] => Array ( [date] => 2009 [plusMinus]=> 0)
        [3] => Array ( [date] => 2010 [plus] => 1 [minus]=>1 )
      ...
      )

So basically I want to check if a value of the date array exists in the plusMinus array. If true the date and values from the plusMinus array shall replace the entry in the date array. If false, the original date array entry is complemented by a [plusMinus] => 0 key-value pair.

The way I have tried to do it is this:

foreach ($filler as $key1 => $value1) 
       {
            foreach ($plusMinus as $key2 => $value2)
                {
                    if ($value1['0'] !== $value2['date'])
                        {
                            $value1['plusMinus'] = '0';
                            $result2[$key1][] = $value1;
                        }
                        elseif ($value1['0'] == $value2['date'])
                        { 
                            if (array_key_exists('plus',$value2))
                            {
                                $value1['plus'] = $value2['plus'];
                                $result2[$key1][]=$value1;
                            }

                            elseif(array_key_exists('minus',$value2))
                            {
                                $value1['minus'] = $value2['minus'];
                                $result2[$key1][]=$value1;
                            } 

                            elseif(array_key_exists('minus',$value2) &&
                                   array_key_exists('plus',$value2))
                            {

                            }
                        }
                } 
       }

$valuesComplete = array();
            foreach ($result2 as $value) {
                $result2 = $value['0'];
                array_push($valuesIncomplete, $result2);
            }
 return $valuesComplete;

Instead of the desired outcome described above I get this:

Array ( [0] => Array 
              ( [0] => 2007 [plus] => 2 ) 
                [1] => Array ( [0] => 2008 [plusMinus => 0 ) 
                [2] => Array ( [0] => 2009 [plusMinus] => 0 ) 
                [3] => Array ( [0] => 2010 [plusMinus] => 0 ) 
                [4] => Array ( [0] => 2011 [plusMinus] => 0 ) 
                [5] => Array ( [0] => 2012 [plusMinus] => 0 ) 
                [6] => Array ( [0] => 2013 [plusMinus] => 0 ) 
              )

What am I missing? Thanks for any help!

Florian Lucke
  • 109
  • 2
  • 11
  • I might just be missing it completely, but don't you have a mismach with $valuesComplete and $valuesIncomplete ? – Borniet Apr 10 '13 at 12:20
  • First of all for brevity kick those elseifs and use continue(in the loop) to see what you are doing please... I do not understand why people complicate things to get in to trouble...:) – Volkan Apr 10 '13 at 12:22

6 Answers6

3

Unfortunately, because of the input data format, I can't see any way to do this that doesn't involve an O(n + m + p) operation. But no matter, you gotta do what you gotta do.

Firstly I would start by filtering the useless elements from the PlusMinus array. Since it's already fairly close to the desired output format, it makes sense to use this as the base of the result.

$temp = array();
foreach ($plusMinus as $item) {
    if (!empty($item['date'])) {
        $temp[$item['date']] = $item;
    }
}

Notice that I used the date as the index of the temporary array we're using to build the result. This is to allow you to easily ensure that the result array is in the correct order, and to quickly check whether an item needs to be added from the Filler array.

Next, we need to add any missing elements from the Filler array:

foreach ($filler as $item) {
    if (!isset($temp[$item[0]])) {
        $temp[$item[0]] = array(
            'date' => $item[0],
            'plusMinus' => 0
        );
    }
}

Now all the data is in the array in the correct format, we just need to sort it:

ksort($temp);

...and get convert it back to an indexed array:

return array_values($temp);

No need for the performance killing nested loops or complex flow control.

See it working

DaveRandom
  • 87,921
  • 11
  • 154
  • 174
0

As I understood you need to add years that not in second array but in first?

In that case you can do:

foreach ($filler as $key1 => $value1)
{
    $ok = false;
    foreach ($plusMinus as $key2 => $value2)
    {
        if($value2['date']==$value1[0])
        {
            $ok = true;
            break;
        }
    }

    if(!$ok)
    {
        $plusMinus[$value1[0]]=array('date'=>$value1[0], 'plusMinus'=>0);
    }
}
Narek
  • 3,813
  • 4
  • 42
  • 58
0
<?php

$a1 = array(array( 2007 ),
            array( 2008 )
           );
$a2 = array(array('plus'=>1, 'date'=>2007),
            array('minus'=>1,'date'=>2008),
            array('plus'=>1, 'minus'=>1, 'date'=>2008)
         );

$r = array();

foreach($a1 as $k1=>$d1) {
   $year = $d1[0];
   foreach( $a2 as $k2=>$d2 ) {
      if( $d2['date'] == $year ) {
         $r[$year]['date'] = $year;
         if(isset($d2['plus'])) {
            $r[$year]['plus'] = $d2['plus'];
         }
         if(isset($d2['minus'])) {
            $r[$year]['minus'] = $d2['minus'];
         }
      }
   }
}

print_r($r);

and result

Array
(
    [2007] => Array
        (
            [date] => 2007
            [plus] => 1
        )

    [2008] => Array
        (
            [date] => 2008
            [minus] => 1
            [plus] => 1
        )

)
Marcin Orlowski
  • 72,056
  • 11
  • 123
  • 141
0
$ar1 = array( array(2007), array(2008), array(2009), array(2010) );

$ar2 = array(
    array("date"=>2007, "plus"=>2),
    array("date"=>2008, "minus"=>1),
    array("date"=>"", "minus"=>1),
    array("date"=>2010, "plus"=>1, "minus"=>1)
);

foreach($ar2 as $key=>$val){
    if(isset($ar1[$key][0]))
        $val["date"] = $ar1[$key][0];
    $ar2[$key] = $val;
}

I am not sure if I understand you correctly but this works fine...

It will work only if you are sure that your both arrays "date" equals one to other..

Svetoslav
  • 4,686
  • 2
  • 28
  • 43
0

This will work just fine.

I did not at all understand your question, but if i got it this is the way: First make your $datearray more understandable like this:

$dateArray = array(2007,2008,2009,2010);
$plusMinus = array(
                    array( 'plus' => 2 ,'date' => 2007),
                    array( 'minus' => 1 ,'date' => 2008),
                    array ( 'minus' => 1 , 'date' => '' ),
                    array ( 'plus' => 1 , 'date' => 2010 , 'minus' => 1 )
              );

You can make it multidimensional later; After that:

foreach($dateArray as $k=>$v)
{
    if(in_array($v,$plusMinus[$k]))
    {
        $filler[$k] = $plusMinus[$k];
    }
    else{
        if(empty($plusMinus[$k]['date']))
        {
            $filler[$k]['date']= $v;
            $filler[$k]['plusMinus'] = 0;
        }
    }
}

This is simple and clean, understandable way with very little code if your arrays will always have the structure you described, meaning the plusMinus values for 2007 are in the cell [0] and the 2007 in the dateArrays is also in the cell [0] like you have shown. I hope i could help.

Lachezar Raychev
  • 2,113
  • 4
  • 24
  • 34
0

This is what I came up with:

To not create the product of both arrays (foreach inside foreach), I first index the $plusMinus array with the date. That will allow to test quickly if a year exists or not:

$years = array_combine(array_column($plusMinus, 'date'), $plusMinus);

This uses the array_column() function of PHP 5.5, if you don't have it you can easily create it your own.

After doing that it is exactly how you wrote it in your own words:

foreach($date as &$entry)
{
    list($year) = $entry;
    $entry = array('date' => $year);
    // check if a value of the date array exists in the plusMinus array.
    if (isset($years[$year])) {
        // If true the date and values from the plusMinus array shall replace the entry in the date array
        $entry += $years[$year];
    } else {
        //  If false, the original date array entry is complemented by a [plusMinus] => 0 key-value pair.
        $entry += array('plusMinus' => 0);
    }
}
unset($entry);

See it i action.

Community
  • 1
  • 1
M8R-1jmw5r
  • 4,896
  • 2
  • 18
  • 26