1

I have a two-dimensional array:

array(
   array( 
    'Friend',
    'Amigo',
    '',
    ''
   ),

   array( 
    'Friend',
    '',
    'Fraund',
    ''
   ),

   array(
    'Thanks',
    'Gracias',
    '',
    ''
   ),

   array(
    'Thanks',
    '',
    'Danke',
    ''
   )
);

Basically, I need to combine inner arrays when they have the same values in a corresponding order. For example, 'friend' and 'thanks' in a current example. Output should be:

array(
   array( 
    'Friend',
    'Amigo',
    'Fraund',
    ''
   ),

   array(
    'Thanks',
    'Gracias',
    'Danke',
    ''
   )
);

Thus, the empty element needs to be overwritten by the corresponding element which has got some value. Cannot figure out how to do it with array_merge.

Kanan Farzali
  • 991
  • 13
  • 23

4 Answers4

1

Well, I'd go about it like this

$final_array = array();
$original_array = array(
    array( 
        'Friend',
        'Amigo',
        '',
        ''
    ),

    array( 
        'Friend',
        '',
        'Fraund',
        ''
    ),

    array(
        'Thanks',
        'Gracias',
        '',
        ''
    ),

    array(
        'Thanks',
        '',
        'Danke',
        ''
        )
    );
 $friends_array = array();
 foreach($original_array[0] as $row) {
     if($row != "") {
         array_push($friends_array, $row);
     }
 }
 foreach($original_array[1] as $row) {
     if($row != "" && !in_array($row, $friends_array)) {
         array_push($friends_array, $row);
     }
 }
 $thanks_array = array();
 foreach($original_array[2] as $row) {
     if($row != "") {
         array_push($thanks_array, $row);
     }
 }
 foreach($original_array[3] as $row) {
     if($row != "" && !in_array($row, $thanks_array)) {
         array_push($thanks_array, $row);
     }
 }
 array_push($final_array, $friends_array, $thanks_array);

You do have a very specific request. Rather odd tbh.

1

Iterate the array, add the values to a new array (indexed by the 1st element in the internal arrays), then use array_values to get your desired output (or leave it indexed as is, which may be beneficial for further data access):

$out = [];
foreach ($input as $val) {
    $key = $val[0]; 
    foreach ($val as $item) {
        if(!empty($item) && $item !=$key){
            $out[$key][]=$item;
        }
    }
    if(!in_array($key, $out[$key])) $out[$key][]=$key;
}
$out = array_values($out);
var_dump($out);

Live working example: http://codepad.viper-7.com/EoRhh2

Steve
  • 20,703
  • 5
  • 41
  • 67
  • Thanks Steve. It does half of the job. But your output is not the same I expect. Firstly, it removes the last empty elements of all inner arrays which should stay. Secondly, the order is very important. It should stay in the same order as in the example. – Kanan Farzali Nov 17 '14 at 14:14
1

You could use array_reduce() like this:

$result = array_values(array_reduce($a, function(array &$final, $current) {
    $key = $current[0];

    if (isset($final[$key])) {
        // replace items that are not an empty string
        $final[$key] = array_replace($final[$key], array_filter($current, 'strlen'));
    } else {
        $final[$key] = $current;
    }
    return $final;
}, []));

The reduce operation creates an array whereby the first word of each array is used as the key; array_replace() updates existing values with new ones if the string is not empty.

The end result is then pulled through array_values() to get rid of the temporary keys that were used during the reduce operation.

Ja͢ck
  • 170,779
  • 38
  • 263
  • 309
  • Thanks, Jack. Nice and simple. The only problem I get is when I loop through the array and put it into a .csv format file, it brings Unicode problems which I didn't have before. For instance, some Spanish letters, or Russian letters look awful. I know it has nothing to do with the current question, but for any help on this I would say Thanks! – Kanan Farzali Nov 17 '14 at 14:32
  • 1
    @KananFarzali Yeah, that shouldn't be related to this answer; you may want to look into [this question](http://stackoverflow.com/questions/279170/utf-8-all-the-way-through) to see what you may have missed. – Ja͢ck Nov 17 '14 at 16:15
0

in php you can use

array_unique($arr1,$arr2);
or
array_merge($arr1,$arr2);

But in your condition you ahve a single array which you have to split into different arrays

$mainArary = array(
  array( 
   'Friend',
   'Amigo',
   '',
   ''
 ),
 array( 
  'Friend',
  '',
  'Fraund',
  ''
 ),
 array(
  'Thanks',
  'Gracias',
  '',
  ''
 ),
 array(
  'Thanks',
  '',
  'Danke',
  ''
 )
);
$first_array = null;
$second_array = null;
$i = 0;
foreach($mainArray[0] as $arr){
  if($i < 2){
  if($prev_array == null){
    $prev_array = $arr;
  } else {
    $prev_array = array_merge($prev_array,$arr);
  } } else {
    if($second_array == null){
    $second_array = $arr;
  } else {
    $second_array = array_merge($second_array ,$arr);
  }
 }
}
print_r($prev_array);
print_r($second_array);

Here is your desired output.

Neeraj Kumar
  • 1,058
  • 1
  • 9
  • 22