Reputation: 1131
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
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
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
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