I want to remove the values from array which are same.
For example:
This is the array.
Array ( [0] => 1 [1] => 63 [2] => 1 )
is there any function or something in core php which return me only the value which is not duplicate i.e value with index number 1 and delete index 0 and 2, I want the result
Array ( [1] => 63)
Is there any way?
You can use array_filter() and array_count_values() to check the count is not greater then 1.
<?php
$data = [1, 63, 1];
$data = array_filter($data, function ($value) use ($data) {
return !(array_count_values($data)[$value] > 1);
});
print_r($data);
https://3v4l.org/uIVLN
Result:
Array
(
[1] => 63
)
Will also work fine with multiple dupes: https://3v4l.org/eJSTY
One option is to use array_count_values to count the values. Loop and push only the 1 values
$arr = array(1,63,1);
$arrKey = array_flip( $arr ); //Store the key
$result = array();
foreach( array_count_values($arr) as $k => $v ) {
if ( $v === 1 ) $result[ $arrKey[$k] ] = $k;
}
echo "<pre>";
print_r( $result );
echo "</pre>";
This will result to:
Array
(
[1] => 63
)
Doc: array_count_values
I believe that the best solution is the following:
function removeDuplicates(array $initialArray) : array
{
// Remove duplicate values from an array
$uniqueValues = array_unique($initialArray);
// Computes the difference of arrays with additional index check
$duplicateValues = array_diff_assoc($initialArray, $uniqueValues);
// Removed any values in both arrays
return array_diff($uniqueValues, $duplicateValues);
}
This solution utilises the following functions in PHP:
array_unique
array_diff_asoc
array_diff
You can use array_keys() with a search value as the second parameter to see how many times a value exists.
$array = [1, 63, 1, 12, 64, 12];
$new = [];
foreach ($array as $value) {
// Get all keys that have this value. If there's only one, save it.
if (count(array_keys($array, $value)) == 1) {
$new[] = $value;
}
}
Demo: https://3v4l.org/G1DCg
I don't know the performance of this compared to the other answers. I leave the profiling to someone else.
Related
Here is an example array I want to split:
(1428,217,1428)
How do I split it in 2 array like this?
(1428,1428)
(217)
I have tried following way but it's only return 1428 array.
$counts = array_count_values($array);
$filtered = array_filter($array, function ($value) use ($counts) {
return $counts[$value] > 1;
});
One way to solve this for your example data is to sort the array and use array_shift to get the first element of the array and store that in an array.
$a = [1428,217,1428];
sort($a);
$b = [array_shift($a)];
print_r($a);
print_r($b);
Result
Array
(
[0] => 1428
[1] => 1428
)
Array
(
[0] => 217
)
You can try this.
$array = array(1428,217,1428);
$array1 = array_slice($array, 0, 2);
$array2 = array_slice($array, 2, 3);
print_r($array1);
print_r($array2);
And the output will like this:-
Array
(
[0] => 1428
[1] => 217
)
Array
(
[0] => 1428
)
In your case it will only return 1428 since array_count_values returns an array with values as keys and their frequency as array value therefore $counts will be equal to array('1428' => 2, '217' => 1);
If I understood your question well you should do something like this:
$array1 = [1428, 217, 1428];
$result = [];
foreach($array1 as $value){
$result[$value][] = $value;
}
This will not create an array for each different value but will create a new element for each unique value in $result. The final value of $result will be array('1428' => [1428, 1428], '217' => [217]) . Which can be easily manipulated as if they were 2 different arrays.
Let me know if this works for you, if not I will try to update my answer according to your specification.
I have 2 arrays -
$array1 =
Array
(
[0] => Array
(
[user_id] => 2
[like_status] => 1
)
[1] => Array
(
[user_id] => 3
[like_status] => 1
)
)
$array2 =
Array
(
[isLoggedIn] => 1
[userId] => 3
)
My requirement is I want to fetch the array where userId = 3. There can be multiple records in $array1 But I only want to fetch the array which have userID = 3, which is in $array2
I am able to get into the condition and match but not able to fetch.
if(array_search($array2['userId'], array_column($array1, 'user_id')) !== False) {
print_r($array1);
}
But it should only return the specific array.
One method is to create a flat array of the userid and use array_intersect to get the matching full arrays.
$userids = array_column($array1, "user_id");
$matching = array_intersect_key($array1, array_intersect($userids, [$array2['user_id']]));
Now $matching will be all the $array1 subarrays where userid is matching $array2['userId'].
array_search($array2['userId'], array_column($array1, 'user_id'))
Will return the index of a matching item or false if there is no matching item. You can use this info to grab the array from $array1.
I.e.
$index = array_search($array2['userId'], array_column($array1, 'user_id')) !== False);
if($index !== false){
print_r($array1[$index]);
}
Note that this assumes that there is only one matching user id in the array - if there are more only the first will be found.
You can do this using foreach also, if you want to like below
foreach ($array1 as $key => $value) {
if($value['user_id'] == $array2['userId'])
{
echo '<pre>'; print_r($value);echo '</pre>';
break;
}
}
Output :
Array (
[user_id] => 3
[like_status] => 1 )
you can achieve this using foreach loop
foreach( $array1 as $val ){
$val['user_id'] == $array2['userId'] ? $result[] = $val : '';
}
echo "<pre>"; print_r( $result );
I have the following two arrays:
Question:
How can i make a 3th array containing the values of the first one
excluding the values of the second one?
Additional information:
The first one is named $checked, the second one is named $exclude.
The values to be excluded are always stored in the second array.
The arrays can change in length, values, and order.
So that in this case i get this result:
Array ( [0] => 26 [1] => 28 [2] => 34 ) <-- array 3:
you can use array_diff():
$checked = array(26,28,34,39,41);
$exclude = array(39, 41);
$result = array_diff($checked, $exclude);
print_r($result);
Result:
Array ( [0] => 26 [1] => 28 [2] => 34 )
$checked = array(11, 26, 38, 13);
$excludeValues = array(26, 38);
foreach ($excludeValues as $exclude) {
if ($key = array_search ( $exclude , $checked )) {
unset($checked[$key]);
}
}
print_r($checked);
Loop through the first array, then check if the value is present in the second array, if not, add it the the third array. Or use the array_diff function as proposed by Uchiha.
foreach($array1 as $items){
if(!in_array($array2,$item)){
$array3[] = $item
}
}
I have two arrays,
$arr_1 = array(01=>5, 02=>3, 03=>2);
$arr_2 = array(01=>3, 02=>4, 03=>0);
what I want to achieve is to have a single array where the final form after adding the two arrays would be,
$arr_3 = array(01=>8, 02=>7, 03=>2);
I tried array_merge but it wasn't the solution.How would I attain the final form?
Try array_map. From the PHP Manual
array_map() returns an array containing all the elements of arr1
after applying the callback function to each one. The number of
parameters that the callback function accepts should match the number
of arrays passed to the array_map()
$arr_1 = array(01=>5, 02=>3, 03=>2);
$arr_2 = array(01=>3, 02=>4, 03=>0);
$arr_3 = array_map('add', $arr_1, $arr_2);
function add($ar1, $ar2){
return $ar1+$ar2;
}
print_r($arr_3);
OUTPUT:
Array ( [0] => 8 [1] => 7 [2] => 2 )
A for loop should handle this:
$max = count($arr_1);
$arr_3 = array();
for($i = 0; $i < $max; $i++){
$arr_3[$i] = intval($arr_1[$i]) + intval($arr_2[$i]);
}
I'm sure there are many other ways to do this, but this is the first one that came to mind. You could also do a foreach loop:
$arr_3 = array();
foreach($arr_1 as $k => $v){
$arr_3[$k] = intval($v) + intval($arr_2[$k]);
}
I'm just winging it here, the foreach is a little tricky to avoid the cartesian effects. Worth a shot though.
If you require adding elements matching by their key not by their position, you could try this:
$array1 = array(1=>5, 2=>3, 3=>2);
$array2 = array(3=>3, 2=>4, 1=>0); //unsorted array
$keys_matched = array_intersect_key ( $array1 , $array2);
foreach ($keys_matched as $key => $value) {
$result[$key] = $array1[$key] + $array2[$key];
}
print_r($result); //Displays: Array ( [1] => 5 [2] => 7 [3] => 5
You would look through both arrays and add each value of each array together then add that result to another array.
foreach($array1 as $val1) {
foreach($array2 as $val2) {
array_push($newArray, intval($val1)+ intval(val2));
}
}
I want to filter a array by a number and update its status in the first array.
I have two array $arr1,$arr2
$arr1 = array(
0=>array('number'=>100,name=>'john'),
1=>array('number'=>200,name=>'johnny')
);
$arr2= array(
0=>array('number'=>300,name=>'r'),
1=>array('number'=>100,name=>'b'),
2=>array('number'=>200,name=>'c')
);
Final output should be an array like this
$arr1 = array(
0=>array('number'=>100,name=>'b'),
1=>array('number'=>200,name=>'c')
);
Any ideas to start off please ?
For specialized array modifications like this, the method of choice is array walk. It allows you to apply a custom function to each element in a given array.
Now, because of your data format, you will have to do a loop. Wrikken is asking if you can retrieve or transform the data to provide faster access. The algorithm below is O(n^2): it will require as many cycles as there are elements in the first array times the number of elements in the second array, or exactly count($arr1) * count($arr2).
function updateNameFromArray($element, $key, $arr2) {
foreach($arr2 as $value) {
if($value['number'] == $element['number']) {
$element['name'] == $value['name'];
break;
}
}
}
array_walk($arr1, "updateNameFromArray", $arr2);
Now, what Wrikken is suggesting is that if your arrays can be changed to be keyed on the 'number' property instead, then the search/replace operation is much easier. So if this were your data instead:
$arr1 = array(
100=>array('number'=>100,name=>'john'),
200=>array('number'=>200,name=>'johnny')
);
// notice the keys are 100 and 200 instead of 0,1
$arr2= array(
300=>array('number'=>300,name=>'r'),
100=>array('number'=>100,name=>'b'),
200=>array('number'=>200,name=>'c')
);
// notice the keys are 300, 100 and 200 instead of 0,1, 2
Then you could do this in O(n) time, with only looping over the first array.
foreach($arr1 as $key => $value) {
if(isset($arr2[$key])) {
$value['number'] = $arr2[$key]['number'];
}
}
Try this. It's not that clean but i think it would work.
<?php
$arr1 = array(0=>array('number'=>100,'name'=>'john'),1=>array('number'=>200,'name'=>'johnny'));
$arr2= array(0=>array('number'=>300,'name'=>'r'),1=>array('number'=>100,'name'=>'b'),2=>array('number'=>200,'name'=>'c'));
foreach( $arr1 as $key=>$data1 )
{
foreach( $arr2 as $key2=>$data2 )
{
if( $data1['number'] == $data2['number'] )
{
$arr1[$key]['name'] = $arr2[$key2]['name'];
}
}
}
print_r( $arr1 );
?>
the output would be :
Array
(
[0] => Array
(
[number] => 100
[name] => b
)
[1] => Array
(
[number] => 200
[name] => c
)
)
There isn't really a simple way for this to be accomplished with generic PHP functions, so, You might need to create mapping arrays.
The way I would approach this, is creating a loop that goes through the first array, and maps the number value as a key to the index of it's place in $arr1 giving you:
$tmp1 = array();
foreach ($arr1 as $key => $number_name) {
$tmp1[$number_name['number']] = $key;
}
This should give you an array that looks like
$tmp1 [
100 => 0,
200 => 1
];
Then I would loop through the second array, get the number value, if that existed as a key in $tmp1, get the associated value (being the key for $arr1), and use that to update the name in $arr1.
// Loop through $arr2
foreach ($arr2 as $number_name) {
// Get the number value
$number = $number_name['number'];
// Find the $arr1 index
if (isset($tmp1[$number])) {
$arr1_key = $tmp1[$number];
// Set the $arr1 name value
$arr1[$arr1_key]['name'] = $number_name['name'];
}
}
<?php
//Set the arrays
$arr1 = array(
array('number'=>100,'name'=>'john'),
array('number'=>200,'name'=>'johnny')
);
$arr2= array(
array('number'=>300,'name'=>'r'),
array('number'=>100,'name'=>'b'),
array('number'=>200,'name'=>'c')
);
// use a nested for loop to iterate and compare both arrays
for ($i=0;$i<count($arr1);$i++):
for ($j=0;$j<count($arr2);$j++):
if ($arr2[$j]['number']==$arr1[$i]['number'])
$arr1[$i]['name']=$arr2[$j]['name'];
endfor;
endfor;
print_r($arr1);
OUTPUT:
Array (
[0] => Array ( [number] => 100 [name] => b )
[1] => Array ( [number] => 200 [name] => c )
)
That being said, you should probably reconsider the very way your data is structured. Do you really need a multi-dimensional array or can you use a simple associative array, like so:
// set the arrays
$arr1 = array(
'john'=>100,
'johnny'=>200
);
$arr2 = array(
'r'=>300,
'b'=>100,
'c'=>200
);
// find values in arr2 common to both arrays
$arr3 = array_intersect($arr2, $arr1);
// change the key of arr1 to match the corresponding key in arr2
foreach ($arr3 as $key=>$value) {
$old_key = array_search($value, $arr1);
$arr1[$key]=$arr1[$old_key];
unset($arr1[$old_key]);
}
print_r($arr1);
OUTPUT:
Array (
[b] => 100
[c] => 200
)