2
if ($item['id_piatto'] === $riga['id_piatto'] && $item['id_portata'] === $riga['id_portata'] && $item['id_dieta'] === $riga['id_dieta']) {
    $item['quantita'] += $riga['quantita'];
} 

Is there a more compact way to compare multiple values of two arrays instead of the one in the code above?

Marenzio
  • 21
  • 2
  • 2
    Whats wrong with what you are doing? – RiggsFolly Sep 10 '20 at 09:59
  • I have a piece of code very similar to the one displayed and the post caught my attention, since OP is missing would you mind elaborating on the comment? As you say there is nothing wrong but I'm just curious as to know wheter existis another -shorter, nicer- way to do this kind of checks. I think everyone likes their code simple and beatiful and it's hard not to ask yourself if something could have be done cleaner every time a line gets too long! @RiggsFolly – Berny Sep 10 '20 at 10:17
  • If those arrays have to be exactly the same, you can use one of the answers on [this question](https://stackoverflow.com/q/5678959/1685196) – Michel Sep 10 '20 at 10:39
  • It works just fine, but with a long condition like that you are bound to go over 120 characters which is not optimal and difficult to read – Marenzio Sep 11 '20 at 10:09

3 Answers3

1

In order to compare several values ​​of two arrays (Not the whole array!) with given keys, such a function is useful:

function array_cmp_keys(array $arr1, array $arr2, array $keys){
  foreach($keys as $key){
    if($arr1[$key] !== $arr2[$key]) return false;
  }
  return true;
}

Testdata:

$item = ['id_piatto' => 1, 'id_portata' => 2, 'id_dieta' => 3, 'xx' => 4];
$riga = ['id_piatto' => 1, 'id_portata' => 2, 'id_dieta' => 3, 'xx' => 5];

How to use:

$keys = ['id_piatto', 'id_portata', 'id_dieta'];

if(array_cmp_keys($item,$riga,$keys)) {
  echo "Equal";
}
else {
  echo "not Equal";
}

"Equal" is output for this test data

jspit
  • 7,276
  • 1
  • 9
  • 17
0

As the top comment points out, your original solution is just fine especially if you are only dealing with a small number of array elements. You only have 3 lines of code and the memory footprint is tiny. Go with your own solution unless you have a good reason not to.

If you have a large number of array elements to compare and a limited number of elements to exclude, you may wish to automate things a bit. Note that this has a memory hit because you're duplicating the array.

<?php

// Original arrays
$first = ['name' => 'tony', 'address' => '123 Main St.', 'position' => 'clerk', 'amount' => 15];
$second = ['name' => 'tony', 'address' => '123 Main St.', 'position' => 'clerk', 'amount' => 23];

// Keys that you want to exclude from the comparison. 
$excludeInComparison = ['amount'];

// Duplicate the arrays but exclude these keys for the comparison.
$firstFiltered = array_diff_key($first, array_flip($excludeInComparison));
$secondFiltered = array_diff_key($second, array_flip($excludeInComparison));

// Compare the filtered arrays
if ($firstFiltered == $secondFiltered) {
    $first['amount'] += $second['amount'];
}
waterloomatt
  • 3,662
  • 1
  • 19
  • 25
-1

You can use PHP's advanced array destructuring syntax, available from PHP 7.1:

['id_piatto' => $a[], 'id_portata' => $a[], 'id_dieta' => $a[]] = $item;
['id_piatto' => $b[], 'id_portata' => $b[], 'id_dieta' => $b[]] = $riga;

$item['quantita'] += ($a === $b) ? $riga['quantita'] : 0;

I think this looks nice and readable, but it really shines when the input arrays have different keys and/or nested structure, I'll give you an example:

$one = [
    'foo' => 1,
    'bar' => [1,2,3],
    'baz' => ['baz_id' => 4]
];
$two = [
    'foo' => 1,
    'bar' => [5,5,3],
    'boo_id' => 4
];

['foo' => $a[], 'bar' => [2 => $a[]], 'baz' => ['baz_id' => $a[]]] = $one;
['foo' => $b[], 'bar' => [2 => $b[]], 'boo_id' => $b[]] = $two;

var_dump($a === $b); // true

Note how I used a numeric index to access the third value in the 'bar' sub-array. Finally, this is much more flexible than the custom function approach in some of the other answers. For detailed info, Check out this blog post about array destructuring in PHP.

Addendum

If it's all about nice looking code and readability, is this really better than the standard approach (maybe structured with some linebreaks)?

if(
        $one['foo'] === $two['foo']
    &&  $one['bar'][2] === $two['bar'][2]
    &&  $one['baz']['baz_id'] === $two['boo_id']
) {
    // Do something...      
}

Apart from the stylistic viewpoint, the standard approach has still two big advantages:

  1. One could easily use an individual comparison operator for each expression

  2. One could implement more advanced boolean logic

One the other hand, the destructuring approach will generate 2 "normalized" subsets of your input arrays on the fly, which could be useful later...

if($a === $b) {
    // Do something
} else {
    return [
        'error_msg' => "Inputs don't match",
        'context' => [
            'expected' => $a,
            'actual' => $b
        ]
    ];
}
Benni
  • 1,023
  • 11
  • 15