Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to remove values from an array if occurring more than one time?

I need to remove values from an array that occur more than one time in the array.

For example:

$value = array(10,10,5,8);

I need this result:

$value = array(5,8);

Is there any in-built function in php?

I tried this, but this will not return my expected result:

$unique = array_unique($value);
$dupes = array_diff_key($value, $unique);
like image 821
Thiyagu Avatar asked Jun 20 '17 13:06

Thiyagu


People also ask

How do you remove all occurrences of an element in an array?

First Create an empty List of Array. Insert all elements of the array into the list. Remove all those element which is you want to remove using the equals() method. Convert the list back to an array and return it.

Can you remove an element from an array in constant time?

However, you can also solve this with an array by simply keeping a list of indices that are deleted. If array[i] is to be deleted, simply keep a new list "deletedIndices" and add "i" to it. Thus, deletion will take constant time and space. There won't be any need to add a sentinel.

Can you add or remove elements of an array once it's created?

Once an array is created, its size cannot be changed. If you want to change the size, you must create a new array and populates it using the values of the old array. Arrays in Java are immutable. To add or remove elements, you have to create a new array.


1 Answers

You can use array functions and ditch the foreach loops if you wish:

Here is a one-liner:

Code:

$value = [10, 10, 5, 8];
var_export(array_keys(array_intersect(array_count_values($value),[1])));

As multi-line:

var_export(
    array_keys(
        array_intersect(
            array_count_values($value),
            [1]
        )
    )
);

Output:

array (
  0 => 5,
  1 => 8,
)

This gets the value counts as an array, then uses array_intersect() to only retain values that occur once, then turns the keys into the values of a zero-index array.

The above snippet works identically to @modsfabio's and @axiac's answers. The ONLY advantage in my snippet is brevity. It is possible that their solutions may outperform mine, but judging speed on relatively small data sets may be a waste of dev time. For anyone processing relatively large data sets, do your own benchmarking to find the technique that works best.


For lowest computational/time complexity, use a single loop and as you iterate conditionally populate a lookup array and unset() as needed.

Code: (Demo) (Crosslink to my CodeReview answer)

$values = [10, 10, 5, 8];

$found = [];
foreach ($values as $index => $value) {
    if (!isset($found[$value])) {
        $found[$value] = $index;
    } else {
        unset($values[$index], $values[$found[$value]]);
    }
}
var_export($values);
// [2 => 5, 3 => 8]

A couple of notes:

  1. If processing float values, using a technique that stores the values as keys (as all of my snippets do), then the results may be incorrect because php will change floats to integers when used as keys.
  2. PHP is consistently much faster at searching for keys than it is at searching for values.
like image 128
mickmackusa Avatar answered Sep 28 '22 05:09

mickmackusa