I am trying to prevent duplicates from occuring in a final array. I am trying to check for duplicates in a list of $media_candidate objects and compile them:
$iterator = 0;
// ensure items in final array are unique
while ((count($final_array) < $numResults) && ($iterator < count($media_data))) {
$media_candidate = $media_data[$iterator++];
if(!in_array($media_candidate['id'], $final_array)){
$final_array[] = $media_candidate;
}
}
As you can see in a print out of $final_array the last three elements are appearing 3 times with id, 343050519221992426_18478933. Any ideas as to what's going on?
First of all: You do not truncate the final array, so that all doublettes will end up at the end.
Second: You are reinventing the wheel: Read up on array_unique()
Edit
Third: After your edit, there is an even easier way:
$final_array=array();
foreach($media_data as $m) $final_array[$m['id']]=$m;
//You might want the next line or not
$final_array=array_values($final_array);
In essence you outsource the uniqueness to the hash keys of the array.
Try with:
if(!in_array($media_candidate['id'], $final_array)){
$final_array[] = $media_candidate['id'];
}
With $final_array[] you add new element at the end of the array.
You are checking $media_candidate['id'] but inserting $media_candidate in $final_array
Try array_unique function like this
$final_array = array_unique($media_candidate);
Related
This question has been asked a thousand times, but each question I find talks about associative arrays where one can delete (unset) an item by using they key as an identifier. But how do you do this if you have a simple array, and no key-value pairs?
Input code
$bananas = array('big_banana', 'small_banana', 'ripe_banana', 'yellow_banana', 'green_banana', 'brown_banana', 'peeled_banana');
foreach ($bananas as $banana) {
// do stuff
// remove current item
}
In Perl I would work with for and indices instead, but I am not sure that's the (safest?) way to go - even though from what I hear PHP is less strict in these things.
Note that after foreach has run, I expected var_dump($bananas) to return an empty array (or null, but preferably an empty array).
1st method (delete by value comparison):
$bananas = array('big_banana', 'small_banana', 'ripe_banana', 'yellow_banana', 'green_banana', 'brown_banana', 'peeled_banana');
foreach ($bananas as $key=>$banana) {
if($banana=='big_banana')
unset($bananas[$key]);
}
2nd method (delete by key):
$bananas = array('big_banana', 'small_banana', 'ripe_banana', 'yellow_banana', 'green_banana', 'brown_banana', 'peeled_banana');
unset($bananas[0]); //removes the first value
unset($bananas[count($bananas)-1]); //removes the last value
//unset($bananas[n-1]); removes the nth value
Finally if you want to reset the keys after deletion process:
$bananas = array_map('array_values', $bananas);
If you want to empty the array completely:
unset($bananas);
$bananas= array();
it still has the indexes
foreach ($bananas as $key => $banana) {
// do stuff
unset($bananas[$key]);
}
for($i=0; $i<count($bananas); $i++)
{
//doStuff
unset($bananas[$i]);
}
This will delete every element after its use so you will eventually end up with an empty array.
If for some reason you need to reindex after deleting you can use array_values
How about a while loop with array_shift?
while (($item = array_shift($bananas)) !== null)
{
//
}
Your Note: Note that after foreach has run, I expected var_dump($bananas) to return an empty array (or null, but preferably
an empty array).
Simply use unset.
foreach ($bananas as $banana) {
// do stuff
// remove current item
unset($bananas[$key]);
}
print_r($bananas);
Result
Array
(
)
This question is old but I will post my idea using array_slice for new visitors.
while(!empty($bananas)) {
// ... do something with $bananas[0] like
echo $bananas[0].'<br>';
$bananas = array_slice($bananas, 1);
}
I have a problem I've been trying to solve for two weeks now, please I need help on this. I do not understand using array well so please bear with me.
I'm trying to combine two arrays and store them in one array so I did this.
$oldvalue =$_SESSION[oldmids]; //value example aa=1,bb=2,cc=3;
$newvalue =$_SESSION[newmids]; //value example 001,002,003;
$result =array();
foreach($oldvalue as $oldval){
$kk =explode('=',$oldval);//i want to keep my tagging so
$oldtag =$kk[0]; // I use explode.
foreach($newvalue as $newid){
$kk =$oldtag.$newid;
$result[] =$kk;
}
}
// print_r($result);
my goal here is to keep my old tag and replace with numeric value, I don't have a problem with
the output, but I only need to get a unique value from my array $result. I tried using array_unique, but failed. Is this the right approach?
I'm not exactly sure what you are trying to do, but I think that array_push() is what you want:
http://www.php.net/array_push
This is my best guess:
$oldvalue =$_SESSION[oldmids]; //value example aa=1,bb=2,cc=3;
$newvalue =$_SESSION[newmids]; //value example 001,002,003;
$result = array();
foreach($oldvalue as $oldval){
$kk =explode('=',$oldval);//i want to keep my tagging so
$oldtag =$kk[0]; // i use explode.
foreach($newvalue as $newid){
$kk =$oldtag.$newid;
array_push($result, $kk);
}
}
print_r($result);
If you have any array $p that you populated in a loop like so:
$p[] = array( "id"=>$id, "Name"=>$name);
What's the fastest way to search for John in the Name key, and if found, return the $p index? Is there a way other than looping through $p?
I have up to 5000 names to find in $p, and $p can also potentially contain 5000 rows. Currently I loop through $p looking for each name, and if found, parse it (and add it to another array), splice the row out of $p, and break 1, ready to start searching for the next of the 5000 names.
I was wondering if there if a faster way to get the index rather than looping through $p eg an isset type way?
Thanks for taking a look guys.
Okay so as I see this problem, you have unique ids, but the names may not be unique.
You could initialize the array as:
array($id=>$name);
And your searches can be like:
array_search($name,$arr);
This will work very well as native method of finding a needle in a haystack will have a better implementation than your own implementation.
e.g.
$id = 2;
$name= 'Sunny';
$arr = array($id=>$name);
echo array_search($name,$arr);
Echoes 2
The major advantage in this method would be code readability.
If you know that you are going to need to perform many of these types of search within the same request then you can create an index array from them. This will loop through the array once per index you need to create.
$piName = array();
foreach ($p as $k=>$v)
{
$piName[$v['Name']] = $k;
}
If you only need to perform one or two searches per page then consider moving the array into an external database, and creating the index there.
$index = 0;
$search_for = 'John';
$result = array_reduce($p, function($r, $v) use (&$index, $search_for) {
if($v['Name'] == $search_for) {
$r[] = $index;
}
++$index;
return $r;
});
$result will contain all the indices of elements in $p where the element with key Name had the value John. (This of course only works for an array that is indexed numerically beginning with 0 and has no “holes” in the index.)
Edit: Possibly even easier to just use array_filter, but that will not return the indices only, but all array element where Name equals John – but indices will be preserved:
$result2 = array_filter($p, function($elem) {
return $elem["Name"] == "John" ? true : false;
});
var_dump($result2);
What suits your needs better, resp. which one is maybe faster, is for you to figure out.
If I have:
$mainarray = some array of things with some repeated values
$array_counted = array_count_values ($mainarray);
How can I find the maximum value in $array_counted?
(This would be the element that appeared most often in $mainarray I think. Its mostly a syntax issue as I am pretty sure I could loop it, but not sure of the syntax to use)
You can find first max value as
$main_array = array(1,2,3,4,5,6,6,6,6,6,6,6);
$max_val = max($main_array);
for find all of max vals
in php < 5.3
function findmax($val)
{
global $max_val;
return $val == $max_val;
}
$max_values_array = array_filter($main_array,'findmax');
in php >= 5.3
$max_values_array = array_filter($main_array,function($val) use ($max_val) { return $val == $max_val; });
echo count($max_values_array);
var_dump($max_values_array);
You could sort the array and take the first, respectively last item out of it, if you don't want to loop.
Since you associate the count with the values with that:
$array_counted = array_count_values ($mainarray);
You only need to sort it afterwards, and return the first key (which is the most occured element):
arsort($array_counted);
print key($array_counted); // returns first key
ok, the guy whos answer I used has deleted his comment so here is how I did it:
I used arsort($array_counted) to sort the array, while keeping index. rsort alone does not work as the result of array_count_values is an associative array. Thank you all.
I'm using a nestedsortable jQuery plugin that gives me the order/sort of the elements serialized.
And example of this serialitzation (root means parent_id=0):
id[1]=root&id[5]=1&id[2]=1&id[3]=1&id[4]=3
First thing I'll do is explode by &:
$serialized = "id[1]=root&id[5]=1&id[2]=1&id[3]=1&id[4]=3";
$exploded = explode("&", $serialized);
But I don't know then how to manage a id[1]=root or id[3]=1. How I can do it?
And another question. In this way I don't know which is how to store the order. When I've the exploded with in array like array("id"=>1, "parent"=>"root"); I've to store the order. I will do it with an index, but how I recognise nested levels?
An example:
$i = 0;
foreach($exploded as $explode)
{
//update every id in MySQL and set parent=$explode["parent"] and order=$i
$i++;
}
But if I've N levels, how I can have a index $i for every one of them?
Thank you in advance!
Rather than exploding, you could try parse_str()
<?php
parse_str("id[1]=root&id[5]=1&id[2]=1&id[3]=1&id[4]=3",$result);
print_r($result);
?>
From there you can work with the array.