Alex
Alex

Reputation: 151

PHP: take out duplicate digits from an array then print them out

I'm probably [super]overthinking this. I'm trying to analyze an array with values like [1,9], [4,6] [5,5], [6,4], [9,1] and duplicate digits (I'm having a super brain fart and can't even remember the term for numbers like this) remove (the last two) so that only [1,9], [4,6] [5,5] are printed.

I was thinking that turning this array into a string and using preg_match, but I'm pretty sure this wouldn't work even if I had the correct regex.

Upvotes: 2

Views: 135

Answers (6)

A.L
A.L

Reputation: 10513

It looks like elements are distributed symmetrically.

We can cut the array in two halves and get only the first half with array_slice():

$array = array(
    array(1,9),
    array(4,6),
    array(5,5),
    array(6,4),
    array(9,1),
);
print_r(array_slice($array, 0, ceil(count($array) / 2)));

Result:

Array(
    [0] => Array(
        [0] => 1
        [1] => 9
    )
    [1] => Array(
        [0] => 4
        [1] => 6
    )
    [2] => Array(
        [0] => 5
        [1] => 5
    )
)

Demo at Codepad.

ceil() is used to round the number up to the next highest integer if there is an even number of items in the array. Example: if there is 3 items in the array, 5 / 2 will return 2.5, we want 3 items so we use ceil(2.5) which gives 3.

Example with 3 items:

$array = array(
    array(1,9),
    array(5,5),
    array(9,1),
);
print_r(array_slice($array, 0, ceil(count($array) / 2)));

Result:

Array(
    [0] => Array(
        [0] => 1
        [1] => 9
    )

    [1] => Array(
        [0] => 5
        [1] => 5
    )
)

Example with 4 items:

$array = array(
    array(1,9),
    array(7,7),
    array(7,7),
    array(9,1),
);
print_r(array_slice($array, 0, ceil(count($array) / 2)));

Result:

Array(
    [0] => Array(
        [0] => 1
        [1] => 9
    )

    [1] => Array(
        [0] => 7
        [1] => 7
    )
)

Upvotes: 1

Jeffrey Lemay
Jeffrey Lemay

Reputation: 58

So I'm actually going to assume your question to have a different meaning than everyone else did. I believe what you're asking is:

How do you filter out array items where a reverse of the item has already been used?

<?php
// The example set you gave
$numberSets = [[1, 9], [4, 6], [5, 5], [6, 4], [9, 1]];

// Initialize an empty array to keep track of what we've seen
$keys = [];

// We use array filter to get rid of items we don't want
// (Notice that we use & on $keys, so that we can update the variable in the global scope)
$numberSets = array_filter($numberSets, function($set) use(&$keys) {
    // Reverse the array
    $set = array_reverse($set);

    // Create a string of the items
    $key = implode('', $set);

    // Get the reverse of the numbers
    $reversedKey = strrev($key);

    // If the palindrome of our string was used, return false to filter
    if (isset($keys[$reversedKey])) {
        return false;
    }

    // Set the key so it's not used again
    // Since $keys is being passed by reference it is updated in global scope
    $keys[$key] = true;

    // Return true to NOT filter this item, since it or it's reverse were not matched
    return true;

});

var_dump($numberSets);

Upvotes: 0

Don&#39;t Panic
Don&#39;t Panic

Reputation: 41820

If you have an array of pairs like this:

$x = array(
    array(1,9),
    array(4,6),
    array(5,5),
    array(6,4),
    array(9,1)
);

Here is one way to get the unique pairs:

foreach ($x as $pair) {
    sort($pair);
    $unique_pairs[implode(',', $pair)] = $pair;
}

This uses string representations of each sorted pair as keys in a new array, so the result will have distinct values by definition.

As far as the printing them out part of your question, once you have the unique values you can loop over them and print them out in whichever format you like, for example:

foreach ($unique_pairs as $pair) { vprintf("[%d,%d]<br>", $pair); }

Upvotes: 3

symcbean
symcbean

Reputation: 48377

The result you suggest treats [a,b] as equivalent to [b,a] which makes the problem a lot more complex. The code below gives the result you asked for, but without really understanding what the problem is that you are trying to fix and whether [1,9] is equivalent to [9,1] in the solution:

$a=array(array(1,9),array(4,6),...
$dup=array();
for ($i=0; $i<count($a) -1; $i++) {
   for ($j=$i+1; $j<count($a); $j++) {
      if (($a[$i][0]==$a[$j[0] && $a[$i][1]==$a[$j[1])
         || ($a[$i][0]==$a[$j[1] && $a[$i][1]==$a[$j[0])) {
            $dup[]=$j;
      }
   }
}
foreach ($dup as $i) {
    unset($a[$i]);
}

Upvotes: 1

Kevin Kopf
Kevin Kopf

Reputation: 14230

This is how I'd do it (and I hope I am not overthinking this :))

$stringArray = array();
$stringArray[] = '1,9';
$stringArray[] = '4,6';
$stringArray[] = '5,5';
$stringArray[] = '6,4';
$stringArray[] = '9,1';

foreach($stringArray as &$numString) {
    $numString = explode(',', $numString);
    usort($numString, function($a, $b) {return $a - $b;});
    $numString = implode(',', $numString);
}


$a = array_unique($a);

print_r($a);

You basically explode every element into a subarray, sort it and then implode it back. After calling the array_unique, you're left with unique values in the array.

The output would be

Array
(
    [0] => 1,9
    [1] => 4,6
    [2] => 5,5
)

Upvotes: 1

sark9012
sark9012

Reputation: 5747

If I'm correct in understanding what you are trying to do, you want to remove the final 2 elements from the array?

There is a function in PHP called array_pop that removes the final element from the array.

$array = array_pop($array);

So if you run this twice, you will remove the final 2 elements from the array.

Upvotes: 1

Related Questions