rfc:array_delete

This is an old revision of the document!


Request for Comments: array_delete() for elements deletion

Introduction

This RFC proposes the addition of a set of two new functions that simplify working with arrays containing a set of unique values or objects that do not have any natural (or distinct) scalar keys that can be used as indices.

While the array-type in PHP does not support set-semantics, these functions simplify working with a set of unique values or objects stored in an array.

array_delete

The first function simplifies removal of a value from an array, when the index is not known:

int array_delete(&$array, $value, $strict = TRUE)

The function is “destructive”, in the sense that it modifies the array in-place - for non-destructive removal, use array_filter().

The int return-value indicates number of removed elements.

To clarify how this function works, here is the PHP equivalent function:

function array_delete(&$array, $value, $strict = TRUE) {
    $count = 0;
    if ($strict) {
        foreach ($array as $key => $item) {
            if ($item === $value) {
                $count++;
                unset($array[$key]);
            }
        }
    } else {
        foreach ($array as $key => $item) {
            if ($item == $value) {
                $count++;
                unset($array[$key]);
            }
        }
    }
    return $count;    
}

If the same value occurs more than once in the given array, all occurrences of the given value will be deleted.

Above example is inefficient, old PHP users should use array_walk().

function array_delete(&$array, $value, $strict = TRUE) {
    $count = 0;
    array_walk($array, funciton($item, $key) use (&$array, &$count, $value, $strict) {
        if ($strict) {
            if ($item === $value) {
                $count++;
                unset($array[$key]);
            }
        } else {
            if ($item == $value) {
                $count++;
                unset($array[$key]);
            }
        }
    };
    return $count;    
}

To prevent accidental deletion, $strict defaults to true - note that this differs from array_search() where the most likely objective is to “find something”.

int array_delete_recursive(&$array, $value, $strict = TRUE)

Recursive variant.

array_udelete

int array_udelete(&$array, callable $callable)

$callable takes 2 parameters, ($value, $key) When callable returns true, element is deleted.

int array_udelete_recursive(&$array, callable $callable)

Recursive variant.

array_add

To complement the array_delete() function, in terms of working with a set of unique values, a second function is proposed:

int array_add(&$array, $value, $strict = TRUE)

This function is “destructive”, like it's counterpart - for non-destructive addition, use array_merge().

The boolean return-value indicates whether or not the specified value was not already present and was added.

To clarify how this function works, here is the PHP equivalent function:

function array_add(&$array, $value, $strict = TRUE) {
  if (false === array_search($value, $array, $strict)) {
    $array[] = $value;
    return true;
  }
  return false;
}

To prevent accidentally adding duplicates, $strict defaults to true - this is consistent with array_delete().

Criticism

These functions allow you to have set-like behavior but without performance benefits traditionally associated with a set.

The array_udelete function is practically identical to array_filter. The difference is that array_udelete would modify the function in-place and array_filter would not. Is it really that hard/unnecessary to reassign the result of array_filter back to the array?

Answer to criticism

If user would like to delete elements, they should use array_walk() rather than array_filter() as it does not delete elements, but creates new array. i.e. Memory and execution is inefficient. Stack overflow and internals thread shows users are not able to choose right API for element deletion. Therefore, array_udelete() is worth to have.

Proposal and Patch

No patch yet.

Reference

Changelog

  • 0.1 Initial version 2012/08/21
  • 0.2 Changed to Rasmus' gist version 2012/08/21
  • 0.3 Changed to array_delete() to have callable and return int. Added array_delete_recursive().
  • 0.4 Reverted callable changes.
  • 0.5 Add array_udelete()
rfc/array_delete.1345598073.txt.gz · Last modified: 2017/09/22 13:28 (external edit)