Remove duplicated values function - php

function remove_values($arr){
$_a = array();
while(list($key,$val) = each($arr)){
$_a[$val] = 1;
}
return array_keys($_a);
}
i can't follow the above function well.i don't know what's the effect of $_a[$val] = 1; anyone can explain it to me thank you

For the purpose of the function, Why not just use array_unique($array)?
Like this
function remove_values($arr){
return array_keys(array_unique($arr));
}
Update:
Ok, Since you are trying to learn. Here is the explanation for the function in the post
function remove_values($arr){
$_a = array(); //Creates a temporary array to store matching
while(list($key,$val) = each($arr)){ //till their is item is array, loop it
$_a[$val] = 1; //Store in the temporary array with array's values as index, thus eliminating the duplicates
//^ Here storing with the value as index IS THE KEY
}
return array_keys($_a); //return only the keys, which in fact are the unique values
}

Well all this does is to insert the value into the key of an array. Since all keys are unique in an array, you will remove all duplicates.
array_keys() simply gives back that array in it's ordinary form.
Example:
$arr = array('red', 'green', 'red');
$arr = remove_values($arr);
gives
array( 'red' => 1,
'green' => 1);
which results in
array('red', 'green');
since "red" can only be a keyvalue once.

Very nice function actually.
$_a[$val] = 1;
makes every element to be signed once, so returned once meaning that duplicates are removed. Than the array_keys($_a) function rebuilds and sorts the array. I liked it.

its assign the value 1 to value part. for ex:
<?php
function remove_values($arr){
$_a = array();
while(list($key,$val) = each($arr)){
$_a[$val] = 1;
}
print_r($_a);
return array_keys($_a);
}
$arr = array('a' => 'apple', 'b' => 'banana', 'c' => 'cranberry');
$sed = remove_values($arr);
print_r($sed);
?>
It return two array values:
Array
(
[apple] => 1
[banana] => 1
[cranberry] => 1
)
Array
(
[0] => apple
[1] => banana
[2] => cranberry
)
Now tis easy for you to understand the effect of value '1'.

Related

How can i convert ARRAY into VARIABLE? [duplicate]

I have an array as the following:
function example() {
/* some stuff here that pushes items with
dynamically created key strings into an array */
return array( // now lets pretend it returns the created array
'firstStringName' => $whatEver,
'secondStringName' => $somethingElse
);
}
$arr = example();
// now I know that $arr contains $arr['firstStringName'];
I need to find out the index of $arr['firstStringName'] so that I am able to loop through array_keys($arr) and return the key string 'firstStringName' by its index. How can I do that?
If you have a value and want to find the key, use array_search() like this:
$arr = array ('first' => 'a', 'second' => 'b', );
$key = array_search ('a', $arr);
$key will now contain the key for value 'a' (that is, 'first').
key($arr);
will return the key value for the current array element
http://uk.php.net/manual/en/function.key.php
If i understand correctly, can't you simply use:
foreach($arr as $key=>$value)
{
echo $key;
}
See PHP manual
If the name's dynamic, then you must have something like
$arr[$key]
which'd mean that $key contains the value of the key.
You can use array_keys() to get ALL the keys of an array, e.g.
$arr = array('a' => 'b', 'c' => 'd')
$x = array_keys($arr);
would give you
$x = array(0 => 'a', 1 => 'c');
Here is another option
$array = [1=>'one', 2=>'two', 3=>'there'];
$array = array_flip($array);
echo $array['one'];
Yes you can infact php is one of the few languages who provide such support..
foreach($arr as $key=>$value)
{
}
if you need to return an array elements with same value, use array_keys() function
$array = array('red' => 1, 'blue' => 1, 'green' => 2);
print_r(array_keys($array, 1));
use array_keys() to get an array of all the unique keys.
Note that an array with named keys like your $arr can also be accessed with numeric indexes, like $arr[0].
http://php.net/manual/en/function.array-keys.php
you can use key function of php to get the key name:
<?php
$array = array(
'fruit1' => 'apple',
'fruit2' => 'orange',
'fruit3' => 'grape',
'fruit4' => 'apple',
'fruit5' => 'apple');
// this cycle echoes all associative array
// key where value equals "apple"
while ($fruit_name = current($array)) {
if ($fruit_name == 'apple') {
echo key($array).'<br />';
}
next($array);
}
?>
like here : PHP:key - Manual

Shuffle the order of keys in an associative array, if they have the same values?

Given an associative array like this, how can you shuffle the order of keys that have the same value?
array(a => 1,
b => 2, // make b or c ordered first, randomly
c => 2,
d => 4,
e => 5, // make e or f ordered first, randomly
f => 5);
The approach I tried was to turn it into a structure like this and shuffle the values (which are arrays of the original keys) and then flatten it back into the original form. Is there a simpler or cleaner approach? (I'm not worried about efficiency, this is for small data sets.)
array(1 => [a],
2 => [b, c], // shuffle these
4 => [d],
5 => [e, f]); // shuffle these
function array_sort_randomize_equal_values($array) {
$collect_by_value = array();
foreach ($array as $key => $value) {
if (! array_key_exists($value, $collect_by_value)) {
$collect_by_value[$value] = array();
}
// note the &, we want to modify the array, not get a copy
$subarray = &$collect_by_value[$value];
array_push($subarray, $key);
}
arsort($collect_by_value);
$reordered = array();
foreach ($collect_by_value as $value => $array_of_keys) {
// after randomizing keys with the same value, create a new array
shuffle($array_of_keys);
foreach ($array_of_keys as $key) {
array_push($reordered, $value);
}
}
return $reordered;
}
I rewrote the entire code, since I found another way which is a lot simpler and faster than the old one(If you are still interested in the old one see the revision):
old code (100,000 executions): Ø 4.4 sec.
new code (100,000 executions): Ø 1.3 sec.
Explanation
First we get all unique values from the array with array_flip(), since then the values are the keys and you can't have duplicate keys in an array we have our unique values. We also create an array $result for then storing our result in it and $keyPool for storing all keys for each value.
Now we loop through our unique values and get all keys which have the same value into an array with array_keys() and save it in $keyPool with the value as key. We can also right away shuffle() the keys array, so that they are already random:
foreach($uniqueValues as $value => $notNeeded){
$keyPool[$value] = array_keys($arr, $value, TRUE);
shuffle($keyPool[$value]);
}
Now we can already loop through our original array and get a key with array_shift() from the $keyPool for each value and save it in $result:
foreach($arr as $value)
$result[array_shift($keyPool[$value])] = $value;
Since we already shuffled the array the keys already have a random order and we just use array_shift(), so that we can't use the key twice.
Code
<?php
$arr = ["a" => 1, "b" => 1, "c" => 1, "d" => 1, "e" => 1, "f" => 2,
"g" => 1, "h" => 3, "i" => 4, "j" => 5, "k" => 5];
function randomize_duplicate_array_value_keys(array $arr){
$uniqueValues = array_flip($arr);
$result = [];
$keyPool = [];
foreach($uniqueValues as $value => $notNeeded){
$keyPool[$value] = array_keys($arr, $value, TRUE);
shuffle($keyPool[$value]);
}
foreach($arr as $value)
$result[array_shift($keyPool[$value])] = $value;
return $result;
}
$result = randomize_duplicate_array_value_keys($arr);
print_r($result);
?>
(possible) output:
Array (
[b] => 1
[g] => 1
[a] => 1
[e] => 1
[d] => 1
[f] => 2
[c] => 1
[h] => 3
[i] => 4
[k] => 5
[j] => 5
)
Footnotes
I used array_flip() instead of array_unique() to get the unique values from the array, since it's slightly faster.
I also removed the if statement to check if the array has more than one elements and needs to be shuffled, since with and without the if statement the code runs pretty much with the same execution time. I just removed it to make it easier to understand and the code more readable:
if(count($keyPool[$value]) > 1)
shuffle($keyPool[$value]);
You can also make some optimization changes if you want:
Preemptively return, if you get an empty array, e.g.
function randomize_duplicate_array_value_keys(array $arr){
if(empty($arr))
return [];
$uniqueValues = array_flip($arr);
$result = [];
//***
}
Preemptively return the array, if it doesn't have duplicate values:
function randomize_duplicate_array_value_keys(array $arr){
if(empty($arr))
return [];
elseif(empty(array_filter(array_count_values($arr), function($v){return $v > 1;})))
return [];
$uniqueValues = array_flip($arr);
$result = [];
//***
}
Here's another way that iterates through the sorted array while keeping track of the previous value. If the previous value is different than the current one, then the previous value is added to a new array while the current value becomes the previous value. If the current value is the same as the previous value, then depending on the outcome of rand(0,1) either the previous value is added to the new list as before, or the current value is added to the new list first:
<?php
$l = ['a' => 1,'b' => 2, 'c' => 2,
'd' => 4,'e' => 5,'f' => 5];
asort($l);
$prevK = key($l);
$prevV = array_shift($l); //initialize prev to 1st element
$shuffled = [];
foreach($l as $k => $v) {
if($v != $prevV || rand(0,1)) {
$shuffled[$prevK] = $prevV;
$prevK = $k;
$prevV = $v;
}
else {
$shuffled[$k] = $v;
}
}
$shuffled[$prevK] = $prevV;
print_r($shuffled);

Find all array keys that has same value

Is there a simpler way to get all array keys that has same value, when the value is unknown.
The problem with array_unique is that it returns the unique array and thus it doesn't find unique values.
That is, for example, from this array:
Array (
[a]=>1000
[b]=>1
[c]=>1000
)
I want to get this
Array (
[a]=>1000
[c]=>1000
)
Another way around this is, if I could find the lonely values, and then their keys, and then use array_diff
This is what I've got so far, looks awful:
$a = array( 'a' => 1000, 'b' => 1, 'c' => 1000 );
$b = array_flip( array_count_values( $a ) );
krsort( $b );
$final = array_keys( $a, array_shift( $b ) );
Update
Using Paulo Freites' answer as a code base, I could get it working pretty easily, maintainable and easy on eyes kind of way… by using the filtering as a static class method I can get the duplicate values from an array by just calling ClassName::get_duplicates($array_to_filter)
private static $counts = null;
private static function filter_duplicates ($value) {
return self::$counts[ $value ] > 1;
}
public static function get_duplicates ($array) {
self::$counts = array_count_values( $array );
return array_filter( $array, 'ClassName::filter_duplicates' );
}
Taking advantage of closures for a more straightforward solution:
$array = array('a' => 1000, 'b' => 1, 'c' => 1000);
$counts = array_count_values($array);
$filtered = array_filter($array, function ($value) use ($counts) {
return $counts[$value] > 1;
});
var_dump($filtered);
This gave me the following:
array(2) {
["a"]=>
int(1000)
["c"]=>
int(1000)
}
Demo: https://eval.in/67526
That's all! :)
Update: backward-compatible solution
$array = array('a' => 1000, 'b' => 1, 'c' => 1000);
$counts = array_count_values($array);
$filtered = array_filter($array, create_function('$value',
'global $counts; return $counts[$value] > 1;'));
var_dump($filtered);
Demo: https://eval.in/68255
Your implementation has a few issues.
1) If there are 2 of value 1000 and 2 of another value, the array_flip will lose one of the sets of values.
2) If there are more than two different values, the array_keys will only find the one value that occurs most.
3) If there are no duplicates, you will still bring back one of the values.
Something like this works always and will return all duplicate values:
<?php
//the array
$a = array( 'a' => 1000, 'b' => 1, 'c' => 1000 );
//count of values
$cnt = array_count_values($a);
//a new array
$newArray = array();
//loop over existing array
foreach($a as $k=>$v){
//if the count for this value is more than 1 (meaning value has a duplicate)
if($cnt[$v] > 1){
//add to the new array
$newArray[$k] = $v;
}
}
print_r($newArray);
http://codepad.viper-7.com/fal5Yz
If you want to get the duplicates in an array try this:
array_unique(array_diff_assoc($array1, array_unique($array1)))
I found this from:
http://www.php.net/manual/en/function.array-unique.php#95203
at the moment I cant figure out another solution...
// target array
$your_array = array('a'=>1000, 'b'=>1, 'c'=>1000);
// function to do all the job
function get_duplicate_elements($array) {
$res = array();
$counts = array_count_values($array);
foreach ($counts as $id=>$count) {
if ($count > 1) {
$r = array();
$keys = array_keys($array, $id);
foreach ($keys as $k) $r[$k] = $id;
$res[] = $r;
}
}
return sizeof($res) > 0 ? $res : false;
}
// test it
print_r(get_duplicate_elements($your_array));
output:
Array
(
[0] => Array
(
[a] => 1000
[c] => 1000
)
)
example #2: - when you have different values multiplied
// target array
$your_array = array('a'=>1000, 'b'=>1, 'c'=>1000, 'd'=>500, 'e'=>1);
// output
print_r(get_duplicate_elements($your_array));
output:
Array
(
[0] => Array
(
[a] => 1000
[c] => 1000
)
[1] => Array
(
[b] => 1
[e] => 1
)
)
if function result has been assigned to $res variable $res[0] gets an array of all elements from original array with first value found more than once, $res[1] gets array of elements with another duplicated-value, etc... function returns false if nothing duplicate has been found in argument-array.
Try this
$a = array( 'a' => 1, 'b' => 1000, 'c' => 1000,'d'=>'duplicate','e'=>'duplicate','f'=>'ok','g'=>'ok' );
$b = array_map("unserialize", array_unique(array_map("serialize", $a)));
$c = array_diff_key($a, $b);
$array = array("1"=>"A","2"=>"A","3"=>"A","4"=>"B","5"=>"B","6"=>"B");
$val = array_unique(array_values($array));
foreach ($val As $v){
$dat[$v] = array_keys($array,$v);
}
print_r($dat);

PHP - Get key name of array value

I have an array as the following:
function example() {
/* some stuff here that pushes items with
dynamically created key strings into an array */
return array( // now lets pretend it returns the created array
'firstStringName' => $whatEver,
'secondStringName' => $somethingElse
);
}
$arr = example();
// now I know that $arr contains $arr['firstStringName'];
I need to find out the index of $arr['firstStringName'] so that I am able to loop through array_keys($arr) and return the key string 'firstStringName' by its index. How can I do that?
If you have a value and want to find the key, use array_search() like this:
$arr = array ('first' => 'a', 'second' => 'b', );
$key = array_search ('a', $arr);
$key will now contain the key for value 'a' (that is, 'first').
key($arr);
will return the key value for the current array element
http://uk.php.net/manual/en/function.key.php
If i understand correctly, can't you simply use:
foreach($arr as $key=>$value)
{
echo $key;
}
See PHP manual
If the name's dynamic, then you must have something like
$arr[$key]
which'd mean that $key contains the value of the key.
You can use array_keys() to get ALL the keys of an array, e.g.
$arr = array('a' => 'b', 'c' => 'd')
$x = array_keys($arr);
would give you
$x = array(0 => 'a', 1 => 'c');
Here is another option
$array = [1=>'one', 2=>'two', 3=>'there'];
$array = array_flip($array);
echo $array['one'];
Yes you can infact php is one of the few languages who provide such support..
foreach($arr as $key=>$value)
{
}
if you need to return an array elements with same value, use array_keys() function
$array = array('red' => 1, 'blue' => 1, 'green' => 2);
print_r(array_keys($array, 1));
use array_keys() to get an array of all the unique keys.
Note that an array with named keys like your $arr can also be accessed with numeric indexes, like $arr[0].
http://php.net/manual/en/function.array-keys.php
you can use key function of php to get the key name:
<?php
$array = array(
'fruit1' => 'apple',
'fruit2' => 'orange',
'fruit3' => 'grape',
'fruit4' => 'apple',
'fruit5' => 'apple');
// this cycle echoes all associative array
// key where value equals "apple"
while ($fruit_name = current($array)) {
if ($fruit_name == 'apple') {
echo key($array).'<br />';
}
next($array);
}
?>
like here : PHP:key - Manual

Add elements to array which has gapped numeric keys to form an indexed array / list

I have an array like this:
$array = [
0 => 'Apple',
2 => 'Orange',
5 => 'Pear',
8 => 'Pear'
]
Is there a way to fill in the missing indexes with a default value (for example, an empty string or null)?
I'd like to insert new elements into the array at the following keys: 1, 3, 4, 6, 7
My result should be:
[
0 => 'Apple',
1 => '',
2 => 'Orange',
3 => '',
4 => '',
5 => 'Pear',
6 => '',
7 => '',
8 => 'Pear'
]
This should be faster for larger arrays. For smaller arrays any method will do.
$existingKeys = array_keys($array);
//you can use any value instead of null
$newKeys = array_fill_keys(range(min($existingKeys), max($existingKeys)), null);
$array += $newKeys;
//optional, probably not needed
ksort($array);
for($i=0;i<count($array);++$i){
$array[$i] = isset($array[$i])? $array[$i] : '';
}
It just fills the missing keys with an empty string, though. Not sure if this suits you.
Edit
Just noticed Perr0_hunter wrote pretty much the same thing before I did :P
you could try a for() from the lowest index to the highest and complete if it's empty
for($i = 0 ;$i <= 8 ; $i++)
{
//if it's not set
if(!isset($array[$i]))
{
//set to empty
$array[$i] = "";
}
}
Additionally you could count first the number of elements on the array and wrap it in a function
function completeIndexes($array)
{
$total = count($array);
for($i = 0 ;$i < $total ; $i++)
{
//if it's not set
if(!isset($array[$i]))
{
//set to empty
$array[$i] = "";
}
}
return $array;
}
Sensibly, you can use a manual loop from 0 to the last numeric key and populate a new array. (Of course, if the array keys are not already sorted in an ascending fashion, you will need to isolate the max() array_key() to find the final key of the newly formed array.)
Or you can use a functional approach to overwrite a default-value-filled, temporary array with the input array's data.
Here are two valid approaches: (Demo)
$result = [];
for (
$i = 0, $last = array_key_last($array);
$i <= $last;
++$i
) {
$result[$i] = $array[$i] ?? null;
}
var_export($result);
And
var_export(
array_replace(
array_fill(0, array_key_last($array), null),
$array
)
);
p.s. Note that array_merge() and the "array union operator" (+) are not suitable techniques to join the default array with the original array -- or at best, the union operator needs to be followed by a ksort() call.
Demo of technique that I do NOT endorse: https://3v4l.org/lCS0n
If what you're trying to do is reorder the array so you get
Array( [0] => Apple [1] => Orange [2] => Pear [3] => Pear )
Just create a new Array and copy the values into it. It will allocate new indexes sequentially
i.e.
$new_array = array();
for( $value in $old_array )
$new_array[] = $value;

Categories