DCHP
DCHP

Reputation: 1131

Only show one instance off return array using explode

Hi i am running the following code.

foreach ($response as $object) {

$basename = basename($object);

$structure = explode("/", $object);

echo $structure[0] . '<br>';


}

this returns the following.

MINOFSOUDUB412
MINOFSOUDUB412
MINOFSOUDUB412
MotionTracker.zip
MotionTracker
MotionTracker
MotionTracker
MotionTracker
MotionTracker
MotionTracker
MotionTracker
MotionTracker
MotionTracker
MotionTracker
MotionTracker
MotionTracker
MotionTracker
MotionTracker
MotionTracker

i only want it to return one unique name like below

MINOFSOUDUB412
MotionTracker.zip
MotionTracker

Can someone help me with this

Thanks

Upvotes: 0

Views: 405

Answers (3)

hakre
hakre

Reputation: 198194

foreach ($response as $object) {
    $basename = basename($object);
    $structure = explode("/", $object); 
    echo $structure[0] . '<br>';
    ...
}

If you want to prevent duplicates in echo'ing out $structure[0], you need to check whether you have had it already, e.g. by keeping a history:

$history = array();
foreach ($response as $object) {
    $name = strstr($object, "/", true);
    if ($name !== false && !isset($history[$name])) {
        $history[$name] = 1;
        echo $name . '<br>';
    }
    ...
}

You probably want to stream line your code. Let's review:

foreach ($response as $object) {

    $basename = basename($object);

    $structure = explode("/", $object);

    echo $structure[0] . '<br>';


}

The line $basename = basename($object); is not used. It can be removed:

foreach ($response as $object) {

    $structure = explode("/", $object);

    echo $structure[0] . '<br>';

}

Then you only need the part of the string until the first "/", the strstr function is handy for that:

foreach ($response as $object) {

    $part = strstr($object, "/", true);
    FALSE === $part && $part = $object;

    echo $part . '<br>';

}

Now as we have already simplified it that much, we can create a simple mapping function:

$map = function($v) {
    $k = strstr($v, "/", true);
    FALSE === $k && $k = $v;
    return $k;
};

and map the $response:

$mapped = array_map($map, $response);

and then unique it:

$unique = array_unique($mapped);

And job done. The code is much more easy to read:

$map = function($v) {
    $k = strstr($v, "/", true);
    FALSE === $k && $k = $v;
    return $k;
};

$mapped = array_map($map, $response);

$unique = array_unique($mapped);

foreach ($unique as $name) {
    echo $name, "<br>\n";
}

The additional benefit is here, in the moment you care about the output, the data to be outputted is already in order and properly available. As output itself counts as one part of your application, it should not be mixed with the data processing. See the IPO Model.

Upvotes: 2

Corbin
Corbin

Reputation: 33457

You will get the best performance out of using the value as an array key:

$unique = array();
while (...) {
    $unique[$name] = true;
}
print_r(array_keys($unique);

This seems a bit crazy at first. After all, why use the string as an array key?

Well: $unique[$name] is O(1) (meaning no matter how large the array is it takes the same amount of time) whereas in_array($name, $unique) is O(n) meaning it grows with how many entries are in the array.

Just for reference the full version of it in your code would be:

$unique = array();

foreach ($response as $object) {
    $basename = basename($object);
    $structure = explode("/", $object);
    $unique[$structure[0]] = true;
    //You could also do: $unique[$structure[0]] = $structure[0];
    //Then your second foreach could be:
    //foreach ($unique as $name)
}

foreach ($unique as $name => $fake) { echo $name . '<br>'; }

The O(n) (slower version) would be:

$unique = array();
foreach ($response as $object) {
    $basename = basename($object);
    $structure = explode("/", $object);
    if (!in_array($structure[0], $unique)) {
        $unique[] = $structure[0];
    }
}

The slower version is slower, but people not intimately familiar with PHP arrays may find it a bit easier to read.

Upvotes: 1

Eugene
Eugene

Reputation: 4389

array_unique would be the right choice. Just pass the exploded array to this function and you will get what you need.

You could look it in here: http://php.net/manual/en/function.array-unique.php

Upvotes: 4

Related Questions