2015-02-04 6 views
0

Я хочу отключить каждый второй элемент из массива. Меня не волнует, если ключи переупорядочены или нет.Удалите каждый n-й элемент из массива

Конечно, я хочу, чтобы это было быстро и элегантно. Возможно ли это, если нет петли и временных переменных?

ответ

0

Мое собственное решение до сих пор:

for ($i = 1; isset($arr[$i]); $i += 2) { 
    unset($arr[$i]); 
} 

Про это, что он не нуждается, если-заявление, кон, что переменная ($i) по-прежнему необходима, и она работает только тогда, когда ключи являются числами и без пробелов.

+0

Я предполагаю, что это единственный путь. Но коррекция будет для ($ i = 2; $ i

+0

@AbhilashCherukat Спасибо, я изменил описание. – flori

0

Если у вас есть массив как

Array 
(
    [0] => test1 
    [1] => test2 
    [2] => test3 
    [3] => test4 
    [4] => test5 
) 

Тогда вы можете пойти с ниже код. Он удалит каждый второй элемент массива.

$i = 1; 
foreach ($demo_array as $key => $row) { 
    if($i%2 == '0') 
    { 
     unset($demo_array[$key]); 
    } 
    $i++; 
} 

Надеюсь, это вам поможет. Позвольте мне знать, нужна ли вам дополнительная помощь.

+0

Про, эта версия работает со всеми типами ключей. Однако я не понимаю, почему 0 является строкой? – flori

+0

Да, это будет работать со всеми типами ключей. Также мы можем использовать его как 0, но хорошая привычка сравнивать значение с двойной цитатой. –

+0

@PHPWeblineindia Почему в мире было бы хорошей привычкой сравнивать переменную, которая может быть только числом против строки? – mickmackusa

0
function arr_unset_sec(&$arr, $key) 
{ 
    if($key%2 == 0) 
    { 
    unset($arr[$key]); 
    } 
} 
array_walk($arr, 'arr_unset_sec'); 

Предполагая, что $ arr может быть некоторым массивом. Проверьте этот фрагмент кода.

0

Другого решения без цикла:

$arr = array('a', 'b', 'c', 'd', 'e'); 
$arr = array_filter($arr, function($k) { return $k % 3 === 0; }, ARRAY_FILTER_USE_KEY); 

Pro, он не нуждается в петле. Минусы, это намного медленнее, чем моя другая версия (с циклом for), выглядит немного страшно и снова зависит от ключей.

+0

@mickmackusa вы правы. Я изменил его, чтобы также поддерживать каждый третий или любой другой. – flori

0

Я предоставлю два метода (array_filter() и цикл foreach()), которые будут использовать условие $i++%$n для целей удаления элементов.

Оба метода будут работать с индексированными и ассоциативными массивами.

  1. $i++ Это пост-инкрементация. Фактически, сначала будет оцениваться значение, а затем - второе.
  2. % Это оператор modulo - он возвращает «остаток» от деления значения слева от значения прав.
  3. Возвращаемое значение из условия будет либо 0, либо положительным целым числом. По этой причине встроенная функция php в стиле «жонглирование» может использоваться для преобразования 0 в false и целых положительных чисел в виде true.
  4. В методе array_filter() синтаксис use() должен использовать &$i, чтобы переменная была «модифицируемой». Без &, $i останется статическим (без изменений после инкрементации).
  5. В способе foreach() Условие инвертировано !() по сравнению с методом array_filter(). array_filter() хочет знать, что «держать»; foreach() хочет знать, что делать до unset().

Код: (Demo)

//       if:$n=2  $n=3  $n=4  $n=5 
$array=['first'=>1, 
     2,     // remove 
     'third'=>3,   //    remove 
     'fourth'=>4,  // remove     remove 
     5,     //          remove 
     6,     // remove  remove 
     'seventh'=>7, 
     'eighth'=>8,  // remove     remove 
     'ninth'=>9];  //    remove 

// if $n is 0 then don't call anything, because you aren't attempting to remove anything 
// if $n is 1 then you are attempting to remove every element, just re-declare as $array=[] 

for($n=2; $n<5; ++$n){ 
    $i=1; // set counter 
    echo "Results when filtering every $n elements: "; 
    var_export(array_filter($array,function()use($n,&$i){return $i++%$n;})); 
    echo "\n---\n"; 
} 

echo "\n\n"; 
// Using a foreach loop will be technically faster (only by a small margin) but less intuitive compared to 
// the literal/immediate interpretation of "array_filter". 

for($n=2; $n<5; ++$n){ 
    $i=1; 
    $copy=$array; 
    foreach($copy as $k=>$v){ 
     if(!($i++%$n)) unset($copy[$k]); // or $i++%$n==0 or $i++%$n<1 
    } 
    echo "Results when unsetting every $n elements: "; 
    var_export($copy); 
    echo "\n---\n"; 
} 

Выход:

Results when filtering every 2 elements: array (
    'first' => 1, 
    'third' => 3, 
    1 => 5, 
    'seventh' => 7, 
    'ninth' => 9, 
) 
--- 
Results when filtering every 3 elements: array (
    'first' => 1, 
    0 => 2, 
    'fourth' => 4, 
    1 => 5, 
    'seventh' => 7, 
    'eighth' => 8, 
) 
--- 
Results when filtering every 4 elements: array (
    'first' => 1, 
    0 => 2, 
    'third' => 3, 
    1 => 5, 
    2 => 6, 
    'seventh' => 7, 
    'ninth' => 9, 
) 
--- 


Results when unsetting every 2 elements: array (
    'first' => 1, 
    'third' => 3, 
    1 => 5, 
    'seventh' => 7, 
    'ninth' => 9, 
) 
--- 
Results when unsetting every 3 elements: array (
    'first' => 1, 
    0 => 2, 
    'fourth' => 4, 
    1 => 5, 
    'seventh' => 7, 
    'eighth' => 8, 
) 
--- 
Results when unsetting every 4 elements: array (
    'first' => 1, 
    0 => 2, 
    'third' => 3, 
    1 => 5, 
    2 => 6, 
    'seventh' => 7, 
    'ninth' => 9, 
) 
--- 
+0

@flori - мой ответ приемлемый или у вас есть вопросы/проблемы? – mickmackusa

Смежные вопросы