PHP: проверьте, удалил ли array_filter какую-либо запись из массива - PullRequest
0 голосов
/ 24 августа 2018

есть ли способ проверить, удалил ли array_filter какое-либо значение из массива?

Решения, о которых я подумал:

$sample_array = ["values"];
$array_copy = $sample_array;

if (array_filter($sample_array, 'fn') === $array_copy) {
    #Some value was deleted from the array
} else {
    #The array was not modified
}

Этот не кажется очень эффективным, так как он должен копировать весь массив.

$sample_array = ["values"];
$array_count = count($sample_array);

if (count(array_filter($sample_array, 'fn')) === $array_count) {
    #The array was not modified
} else {
    #Some value was deleted from the array
}

Этот кажется более эффективным, хотя мне было интересно, есть ли более элегантный подход к проблеме.

Заранее спасибо.

Ответы [ 5 ]

0 голосов
/ 24 августа 2018

Если вы хотите отслеживать удаленные элементы, вы можете сделать что-то вроде этого.

$sample_array = ['values', 'test'];
$removed = []; // Contains all the removed values.

$new_array = array_filter($sample_array, function($value) use (&$removed) {
    if($value == 'test') {
        $removed[] = $value; // Adds the value to the removed array.
        return false;
    }

    return true;
});

print_r($removed);
0 голосов
/ 24 августа 2018

Вы можете использовать замыкание для изменения состояния логической переменной:

$sample_array = [1,2,3,4];
$array_changed = false;

//Use closure to change $array_changed
print_r(array_filter($sample_array, function($var) use (&$array_changed) {
    $check = (!($var & 1));
    $array_changed = $array_changed?:$check;
    return $check;
}));

if ($array_changed) {
    #Some value was deleted from the array
} else {
    #The array was not modified
}

[РЕДАКТИРОВАТЬ]

Это простой Speedtest из ваших решений по сравнению с моим:

/**********************SPEEDTEST**************************/

function fn ($var) {
    return (!($var & 1));
}
$sample_array = [1,2,3,4];

$before = microtime(true);

for ($i=0 ; $i<100000 ; $i++) {

    $array_changed = false;

    //Use closure to change $array_changed
    array_filter($sample_array, function($var) use (&$array_changed) {
        $check = (!($var & 1));
        $array_changed = $array_changed?:$check;
        return $check;
    });
    if ($array_changed) {
        #Some value was deleted from the array
    } else {
        #The array was not modified
    }

}

$after = microtime(true);
echo "Using closure:      " . ($after-$before)/$i . " sec/run\n";

echo '<br>';
/*******************************************************/

$before = microtime(true);

for ($i=0 ; $i<100000 ; $i++) {

    $array_copy = $sample_array;

    if (array_filter($sample_array, 'fn') === $array_copy) {
        #Some value was deleted from the array
    } else {
        #The array was not modified
    }

}

$after = microtime(true);
echo "Using array copy:    " . ($after-$before)/$i . " sec/run\n";

echo '<br>';
/*******************************************************/

$before = microtime(true);

for ($i=0 ; $i<100000 ; $i++) {

    $array_count = count($sample_array);

    if (count(array_filter($sample_array, 'fn')) === $array_count) {
        #The array was not modified
    } else {
        #Some value was deleted from the array
    }

}

$after = microtime(true);
echo "Using array count:   " . ($after-$before)/$i . " sec/run\n";

Результаты:

Using closure:       9.1402053833008E-7 sec/run
Using array copy:    4.9885988235474E-7 sec/run
Using array count:   5.5881977081299E-7 sec/run

Может быть, это помогает с принятием решений:)

0 голосов
/ 24 августа 2018

Использование count () - ИМХО самое элегантное решение, и, я подозреваю, может быть намного более эффективным - вам нужно его измерить. OTOH, для вашего рассмотрения ...

 function fn($arg, $mode='default')
 {
     static $matched;

     if ('default'==$mode) {
        $result=real_filter_fn($arg);
        $matched+=$result ? 1 : 0;
        return $result;
     }
     $result=$matched;
     $matched=0;
     return $result;
 }
0 голосов
/ 24 августа 2018

Вы можете расширить свою функцию для отслеживания самого изменения.

$array = [1, 2, 3, 4];
$changed = 0;

$new = array_filter($array, function($e) use (&$changed) {
    $result = $e <= 2;
    if(!$result) $changed++;
    return $result;
});

Возвращает $changed как 2.

0 голосов
/ 24 августа 2018

Используйте array_diff для сравнения двух массивов.

if(array_diff($array_copy, $sample_array))
    echo "not same";
...