I have two arrays:
$A = array('a','b','c','d')
$c = array('b','c','e','f')
I want to get a new array containing items not in array $A. So it would be:
$result = array('e','f');
because 'e' and 'f' are not in $A.
Use array_diff
print_r(array_diff($c, $A)); returns
Array
(
[2] => e
[3] => f
)
Use array_diff for this task. As somewhat annoying it does not return all the differences between the two arrays. Only the elements from the first array passed which are not found in any other array passed as argument.
$array1 = array('a','b','c','d');
$array2 = array('b','c','e','f');
$result = array_diff($array2, $array1);
array_diff()
Pseduo Code for General Implementation
Disclaimer: Not familiar with PHP, other answers indicate there are a lot quicker ways of doing this :)
Loop through your first array:
// Array of results
array results[];
// Loop through all chars in first array
for i = 0; i < A.size; i++
{
// Have we found it in second array yet?
bool matched = false;
// Loop each character in 2nd array
for j = 0; j < C.size; j++
{
// If they match, exit the loop
if A[i] == C[J] then
matched = true;
exit for;
}
// If we have a match add it to results
if matches == true then results.add(A[i])
}
Related
I got array like:
$array = array(
3A32,
4565,
7890,
0012,
A324,
9002,
3200,
345A,
0436
);
Then I need to find which elements has two numbers. The value of number can change.
If values were:
$n1 = 0;
$n2 = 3;
For that search preg_match() should return (3200,0436)
If values were:
$n1 = 0;
$n2 = 0;
preg_match() should return (0012,3200,9002)
Any idea?
Thanks.
I got your logic after looking multiple times on your input array as well as output based on given numbers.
Since i am not good in regular expression at all, i will go to find out answer with commonly know PHP functions.
1.Create a function which takes initial array as well as those search numbers in array form (so that you can search any number and any length of numbers).
2.Now iterate over initial array, split each value to convert to array and do array_count_value() for both split array and numbers array. now apply check and see exact match found or not?
3.Assign this match to a new array declared under the function itself.
4.Return this array at the end of function.
$n1 = 0;
$n2 = 0;
function checkValues($array,$numbers=array()){
$finalArray = [];
if(!empty($numbers)){
foreach($array as $arr){
$splitArr = str_split($arr);
$matched = true;
$count_number_Array = array_count_values($numbers);
$count_split_array = array_count_values($splitArr);
foreach($count_number_Array as $key=>$value){
if(!isset($count_split_array[$key]) || $count_split_array[$key] < $value){
$matched = false;
break;
}
}
if($matched === true){
$finalArray[] = $arr;
}
}
}
return $finalArray;
}
print_r(checkValues($array, array($n1,$n2)));
Output: https://3v4l.org/7uWfC And https://3v4l.org/Tuu5m And https://3v4l.org/fEKTO
Instead of using preg_match, you might use preg_grep and dynamically create a pattern that will match the 2 values in each order using an alternation.
^[A-Z0-9]*0[A-Z0-9]*3[A-Z0-9]*|[A-Z0-9]*3[A-Z0-9]*0[A-Z0-9]*$
The character class [A-Z0-9] matches either a char A-Z or a digit 0-9.
Regex demo | Php demo
If you want to use other characters, you could also take a look at preg_quote to handle regular expression characters.
function getElementWithTwoValues($n1, $n2) {
$pattern = "/^[A-Z0-9]*{$n1}[A-Z0-9]*{$n2}[A-Z0-9]*|[A-Z0-9]*{$n2}[A-Z0-9]*{$n1}[A-Z0-9]*$/";
$array = array(
"3A32",
"4565",
"7890",
"0012",
"A324",
"9002",
"3200",
"345A",
"0436"
);
return preg_grep($pattern, $array);
}
print_r(getElementWithTwoValues(0, 3));
print_r(getElementWithTwoValues(0, 0));
Output
Array
(
[6] => 3200
[8] => 0436
)
Array
(
[3] => 0012
[5] => 9002
[6] => 3200
)
I have two arrays:
$currentArr = ['apples','oranges','pears'];
$newArr = ['apples','oranges','pears', 'grapes'];
I need to formulate logic that will:
a) check the $newArr against the $currentArr and tell me what was REMOVED and what was ADDED
b) push the removed values onto a new separate array and push the added values onto a new separate array
as I am not extremely well versed in PHP, is this possible? if so, how can I do so?
array_diff() is what you need:
Returns an array containing all the entries from array1 that are not present in any of the other arrays.
<?php
$currentArr = ['apples','oranges','pears','test'];
$newArr = ['apples','oranges','pears', 'grapes'];
$removed = array_diff($currentArr, $newArr);
print_r($removed);
// output:
// Array ( [3] => test )
// switch the order to get the added items:
$added = array_diff($newArr, $currentArr);
print_r($added);
// output:
// Array ( [3] => grapes )
arr_diff($a,$b) is a function that returns a new array containing the items in $a that are not in $b.
$removed = array_diff($currentAr,$newArr);
$added = array_diff($newArr,$currentAr);
With the following arrays i PHP:
$array1 = array(2,9,7);
$array2 = array(6,8,2);
How would write the following statement in code:
If any value of $array1 matches any single value of $array2, then $match = true;
I imagine this is simple, but I can't figure it out.
if ( count(array_intersect($array1, $array2)) > 0 ) {
$match = true;
}
I a string that is coming from my database table say $needle.
If te needle is not in my array, then I want to add it to my array.
If it IS in my array then so long as it is in only twice, then I still
want to add it to my array (so three times will be the maximum)
In order to check to see is if $needle is in my $haystack array, do I
need to loop through the array with strpos() or is there a quicker method ?
There are many needles in the table so I start by looping through
the select result.
This is the schematic of what I am trying to do...
$haystack = array();
while( $row = mysql_fetch_assoc($result)) {
$needle = $row['data'];
$num = no. of times $needle is in $haystack // $haystack is an array
if ($num < 3 ) {
$$haystack[] = $needle; // hopfully this adds the needle
}
} // end while. Get next needle.
Does anyone know how do I do this bit:
$num = no. of times $needle is in $haystack
thanks
You can use array_count_values() to first generate a map containing the frequency for each value, and then only increment the value if the value count in the map was < 3, for instance:
$original_values_count = array_count_values($values);
foreach ($values as $value)
if ($original_values_count[$value] < 3)
$values[] = $value;
As looping cannot be completely avoided, I'd say it's a good idea to opt for using a native PHP function in terms of speed, compared to looping all values manually.
Did you mean array_count_values() to return the occurrences of all the unique values?
<?php
$a=array("Cat","Dog","Horse","Dog");
print_r(array_count_values($a));
?>
The output of the code above will be:
Array (
[Cat] => 1,
[Dog] => 2,
[Horse] => 1
)
There is also array_map() function, which applies given function to every element of array.
Maybe something like the following? Just changing Miek's code a little.
$haystack_count = array_count_values($haystack);
if ($haystack_count[$needle] < 3)
$haystack[] = $needle;
I'm looking for an efficient algorithm for detecting equal values in an array of integers N size. It must return the indices of the matches.
Alas, I can't think of anything more clever then brute force with two loops.
Any help will be appreciated.
Thanks!
You could intersect the array. This finds all the values of array2 that are in array1
$array1 = array("a" => "green", "b" => "brown", "c" => "blue", "red");
$array2 = array("a" => "green", "yellow", "red");
$result_array = array_intersect_assoc($array1, $array2);
print_r($result_array);
Would return
Array
(
[a] => green
)
It returns an array with all of the keys and values of the matches. Basically you can provide an infinite number of arguments to the array_insert_assoc:
array_intersect_assoc($base_array, $arr1, $arr2 ...);
It will search $base_array for the values that are in all the subsequent arrays. That means that the key and value will be taken from the $base_array
You could also compare the keys by using:
array_intersect_keys($base_array, $arr1, $arr2, $arr3);
These loops are O(N^2). Is N big? If so, can you sort the array O(NlogN), then scan it O(N)? ... or am I missing something?
You can use a set to hold the recent values. For example,
results = empty list
set = empty set
foreach key, val in array:
if val is not in set: add val to set
else: add key to results
return results
Each look up of set is O(1), so this algo will results in O(n) instead of O(n^2) if nested-loop is used.
In case you want to keep track of multi-occurence like this array 1, 2, 3, 3, 2, 1 you can use a hash table with key is the value and value (of the corresponding key in table) is the list of indices. The result for the given array will look lik {1:0, 5; 2: 1, 4; 3: 2, 3}.
results = empty hashtable
for each key, val in array:
if val is not in results:
results[val] = new list()
results[val].append(key)
return results
Perhaps this?
$arr = array_map('unserialize', array_unique(array_map('serialize', $arr)));
From the question: How to remove duplicated 2-dimension array in PHP?
if ($arr !== array_map('unserialize', array_unique(array_map('serialize', $arr))))
{
// found duplicates
}
You don't have to go through all the array again for each element. Only test an element with the subsequent element in the array:
$array = /* huge array */;
$size = count($array);
for($i = 0; $i < $size; $i++)
{
for($j = $i + 1; $j < $size; $j++) // only test with the elements after $i
{
if($array[$i] == $array[$j])
return true; // found a duplicate
}
return false; // found no duplicate
}
That's the most efficient way I can think of. Adapt it to your need as you will.
If one of your arrays is reasonably static (that is you are comparing to the same array several times ) you could invert it.
That is set up another array which is keyed by value and returns the index into the real array.
$invert = array();
foreach ($cmptoarray as $ix => $ival) {
$invert[$ival] = $ix;
}
Then you simply need an if ( isset($invert[$compfrmarray[$i]) ) .... to check the number.
Note: this is only worth doing if you compare against the same array several times!
Just use an associative array mapping a value to its index:
foreach($array1 as $index => $value) {
$aa[$value] = $index;
}
foreach($array2 as $index => $value) {
if(isset($aa[$value])) {
echo 'Duplicate: . Index 1: '.$aa[$value].' Index 2: '.$index.'.';
}
}