Php: remove (different cases) duplicates from array - php

probably an already discussed topic, but in Php I did not found an answer
Is there a simpler way to realize in what follows:
$a = array("hello","hello","Hello","world","worlD");
$p=array();
foreach( $a as $v ){
$p[strtolower($v)] = "";
}
print_r($p);
keep one single element, in small-case, for the array

something like:
$p = array_unique(array_map('strtolower', $a));

You can use array_flip to swap keys and values:
$a = array_flip(array_map('strtolower', $a));

Related

getting duplicate entries from array (instead of just removing them)

I have an array with possible duplicate values, and I want not only to remove them (i use array_unique for that), but extract them in anothr array.
i.e.
$a = array(1,2,2,3,4,4,5,6,6,6);
$b = array_unique($a); // has 1,2,3,4,5,6
I want a third array ($c) with the duplicates only
that is, with [2,4,6] or [2,4,6,6] (either would do)
whats the easiest way of doing it?
I tried $c = array_diff($a,$b), but gives an empty array, since it is removing all of the occurrences of $b from $a (because, of course, they occur at least once in $b)
I also thought of array_intersect, but it result in an array exactly like $a
Is there a direct function in php to achieve this? How to do it?
I also found such solution on Internet:
$c = array_unique( array_diff_assoc( $a, array_unique( $a ) ) );
But it doesn't seem easy to understand
You can use array_count_values to count the # of occurrences of each element and use array_filter to only keep those that occur more than once.
$a = array(1,2,2,3,4,4,5,6,6,6);
$b = array_count_values($a);
$c = array_filter($b,function($val){ return $val > 1; });
$c = array_keys($c);
print_r($c);
If your input array is sorted you can find dupes by looping through the array and checking if the previous element is equal to the current one
$a = array(1,2,2,3,4,4,5,6,6,6);
$dupes = array();
foreach($a as $i => $v) {
if($i > 0 && $a[--$i] === $v)
$dupes[] = $v;
}
print_r($dupes);

How can I use in_array if the needle is an array?

I have 2 arrays, the value will be loaded from database, below is an example:
$arr1 = array(1,2,3);
$arr2 = array(1,2,3,4,5,6,7);
What I want to do is to check if all the values in $arr1 exist in $arr2. The above example should be a TRUE while:
$arr3 = array(1,2,4,5,6,7);
comparing $arr1 with $arr3 will return a FALSE.
Normally I use in_array because I only need to check single value into an array. But in this case, in_array cannot be used. I'd like to see if there is a simple way to do the checking with a minimum looping.
UPDATE for clarification.
First array will be a set that contains unique values. Second array can contain duplicated values. They are both guaranteed an array before processing.
Use array_diff():
$arr1 = array(1,2,3);
$arr2 = array(1,2,3,4,5,6,7);
$arr3 = array_diff($arr1, $arr2);
if (count($arr3) == 0) {
// all of $arr1 is in $arr2
}
You can use array_intersect or array_diff:
$arr1 = array(1,2,3);
$arr2 = array(1,2,3,4,5,6,7);
if ( $arr1 == array_intersect($arr1, $arr2) ) {
// All elements of arr1 are in arr2
}
However, if you don't need to use the result of the intersection (which seems to be your case), it is more space and time efficient to use array_diff:
$arr1 = array(1,2,3);
$arr2 = array(1,2,3,4,5,6,7);
$diff = array_diff($arr1, $arr2);
if ( empty($diff) ) {
// All elements of arr1 are in arr2
}
You can try use the array_diff() function to find the difference between the two arrays, this might help you. I think to clarify you mean, all the values in the first array must be in the second array, but not the other way around.
In my particular case I needed to check if a pair of ids was processed before or not. So simple array_diff() did not work for me.
Instead I generated keys from ids sorted alphabetically and used them with in_array:
<?php
$pairs = array();
// ...
$pair = array($currentId, $id);
sort($pair);
$pair = implode('-', $pair);
if (in_array($pair, $pairs)) {
continue;
}
$pairs[$pair] = $pair;
This is probably not an optimum solution at all but I just needed it for a dirty script to be executed once.

Interleaving multiple arrays into a single array

I need to merge several arrays into a single array. The best way to describe what I'm looking for is "interleaving" the arrays into a single array.
For example take item one from array #1 and append to the final array. Get item one from array #2 and append to the final array. Get item two from array #1 and append...etc.
The final array would look something like this:
array#1.element#1
array#2.element#1
.
.
.
The "kicker" is that the individual arrays can be of various lengths.
Is there a better data structure to use?
for example,
function array_zip_merge() {
$output = array();
// The loop incrementer takes each array out of the loop as it gets emptied by array_shift().
for ($args = func_get_args(); count($args); $args = array_filter($args)) {
// &$arg allows array_shift() to change the original.
foreach ($args as &$arg) {
$output[] = array_shift($arg);
}
}
return $output;
}
// test
$a = range(1, 10);
$b = range('a', 'f');
$c = range('A', 'B');
echo implode('', array_zip_merge($a, $b, $c)); // prints 1aA2bB3c4d5e6f78910
If the arrays only have numeric keys, here's a simple solution:
$longest = max( count($arr1), count($arr2) );
$final = array();
for ( $i = 0; $i < $longest; $i++ )
{
if ( isset( $arr1[$i] ) )
$final[] = $arr1[$i];
if ( isset( $arr2[$i] ) )
$final[] = $arr2[$i];
}
If you have named keys you can use the array_keys function for each array and loop over the array of keys instead.
If you want more than two arrays (or variable number of arrays) then you might be able to use a nested loop (though I think you'd need to have $arr[0] and $arr[1] as the individual arrays).
I would just use array_merge(), but that obviously depends on what exactly you do.
This would append those arrays to each other, while elements would only be replaced when they have the same non-numerical key. And that might not be a problem for you, or it might be possible to be solved because of attribute order, since the contents of the first arrays' elements will be overwritten by the later ones.
If you have n arrays, you could use a SortedList, and use arrayIndex * n + arrayNumber as a sort index.

PHP: Apply a function to multiple variables without using an array

I have a function (for ease, I'll just use count()) that I want to apply to maybe 4-5 different variables. Right now, I am doing this:
$a = count($a);
$b = count($b);
$c = count($c);
$d = count($d);
Is there a better way? I know arrays can use the array_map function, but I want the values to remain as separate values, instead of values inside of an array.
Thanks.
I know you said you don't want the values to be in an array, but how about just creating an array specifically for looping through the values? i.e.:
$arr = Array($a, $b, $c, $d);
foreach ($arr as &$var)
{
$var = count($var);
}
I'm not sure if that really is much tidier than the original way, though.
If you have a bunch of repeating variables to collect data your code is poorly designed and should just be using an array to store the values, instead of dozens of variables. So perhaps you want something like:
$totals = array("Visa"=>0,"Mastercard"=>0,"Discover"=>0,"AmericanExpress"=>0);
then you simply add to your array element (say from a while loop from your SQL or whatever you are doing)
$totals['Visa'] += $row['total'];
But if you really want to go down this route, you could use the tools given to you, if you want to do this with a large batch then an array is a good choice. Then foreach the array and use variable variables, like so:
$variables = array('a','b','c'...);
foreach ( $variables as $var )
{
${$var} = count(${var});
}
What Ben and TravisO said, but use array_walk for a little cleaner code:
$arr = Array($a, $b, $c, $d);
array_walk($arr, count);
You can use extract to get the values back out again.
//test data
$a = range(1, rand(4,9));
$b = range(1, rand(4,9));
$c = range(1, rand(4,9));
//the code
$arr = array('a' => $a, 'b' => $b, 'c' => $c);
$arr = array_map('count', $arr);
extract($arr);
//whats the count now then?
echo "a is $a, b is $b and c is $c.\n";
How do you measure "better"? You might be able to come up with something clever and shorter, but what you have seems like it's easiest to understand, which is job 1. I'd leave it as it is, but assign to new variables (e.g. $sum_a, ...).

How to compare two arrays and remove matching elements from one for the next loop?

How else might you compare two arrays ($A and $B )and reduce matching elements out of the first to prep for the next loop over the array $A?
$A = array(1,2,3,4,5,6,7,8);
$B = array(1,2,3,4);
$C = array_intersect($A,$B); //equals (1,2,3,4)
$A = array_diff($A,$B); //equals (5,6,7,8)
Is this the simplest way or is there a way to use another function that I haven't thought of? My goal is to have an array that I can loop over, pulling out groups of related content (I have defined those relationships elsewhere) until the array returns false.
You've got it. Just use array_diff or array_intersect. Doesn't get much easier than that.
Edit:
For example:
$arr_1 = array_diff($arr_1, $arr_2);
$arr_2 = array_diff($arr_2, $arr_1);
Source
Dear easy and clean way
$clean1 = array_diff($array1, $array2);
$clean2 = array_diff($array2, $array1);
$final_output = array_merge($clean1, $clean2);
See also array_unique. If you concatenate the two arrays, it will then yank all duplicates.
Hey, even better solution: array _ uintersect.
This let's you compare the arrays as per array_intersect but then it lets you compare the data with a callback function.
Try to this
$a = array(0=>'a',1=>'x',2=>'c',3=>'y',4=>'w');
$b = array(1=>'a',6=>'b',2=>'y',3=>'z');
$c = array_intersect($a, $b);
$result = array_diff($a, $c);
print_r($result);

Categories