Php, in_array with no exactly match - php

I want to do the following:
$a = array();
$a[] = array(1,2);
$a[] = array(2,5);
$a[] = array(3,4);
var_dump (in_array(array(2,5), $a));
this returns OK, as it expected, but if the source array is not fully matched:
$a = array();
$a[] = array(1,2, 'f' => array());
$a[] = array(2,5, 'f' => array());
$a[] = array(3,4, 'f' => array());
var_dump (in_array(array(2,5), $a));
it returns false. Is there a way to do it with the built-in way, or I have to code it?

in_array() is just not the thing that you should use for this issue. Because it will compare values with type casting, if that's needed. Instead, you may use plain loop or something like:
function in_array_array(array $what, array $where)
{
return count(array_filter($where, function($x) use ($what)
{
return $x===$what;
}))>0;
}
So then
var_dump(in_array_array(array(2, 5), $a)); //true

$needle = array(2, 5);
$found = array_reduce($a, function ($found, array $array) use ($needle) {
return $found || !array_diff($needle, $array);
});
This does an actual test of whether the needle is a subset of an array.
function subset_in_array(array $needle, array $haystack) {
return array_reduce($haystack, function ($found, array $array) use ($needle) {
return $found || !array_diff($needle, $array);
});
}
if (subset_in_array(array(2, 5), $a)) ...

Related

Array comparison and re-order in PHP

Let's say I Have two arrays.
$arr1 = ['A','B','C','D'];
$arr2 = ['C','D'];
now compare two arrays.if there is no match for value of $arr1 in $arr2 then index is left empty.
for the above arrays output should be:
$arr3 = ['','','C','D']
I tried array_search() function.But couldn't achieve desired output.
Any possible solutions?
You can use foreach with in_array and array_push like:
$arr1 = ['A','B','C','D'];
$arr2 = ['C','D'];
$arr3 = [];
foreach($arr1 as $value){
$arr3[] = (in_array($value, $arr2)) ? $value : '';
}
print_r($arr3);
/*
Result
Array
(
[0] =>
[1] =>
[2] => C
[3] => D
) */
Foreach the first array then test with in_array if exist, if true push into array 3 else push empty value
You can use the following function. In the following code, the function search_in_array return true and false based on the searching within the 2nd array. So you can push the empty or searched value in final array.
<?php
$arr1 = array('A','B','C','D');
$arr2 = array('C','D');
$arr3 = array();
function search_in_array ($value, $array)
{
for ($i=0; $i<count($array); $i++)
{
if ($value == $array[$i])
{
return true;
}
}
return false;
}
for ($i=0; $i<count($arr1); $i++)
{
$value = $arr1[$i];
$result = search_in_array ($value, $arr2);
if ($result)
{
array_push ($arr3, $value);
}
else
{
array_push ($arr3, '');
}
}
print_array($arr3);
?>

2 PHP arrays for merge

How to delete element from array as it has partial in another?
Other words, I need to compare 2 array likely in_array php function, but partially.
Code:
$a = ['abc', 'cde', 'efg', 'hi'];
$b = ['bce', 'ifg', 'hig'];
// return $b without 'hig' because in $a has partially 'hi'
Thanks very much for any solution!
If you want to make any string in $b not have any string in $a as a substring. demo
<?
$a = ['abc', 'cde', 'efg', 'hi'];
$b = ['bce', 'ifg', 'hig'];
$b = array_filter($b, function($v) use($a){
foreach($a as $str){
if(strpos($v, $str) !== false)
return false;
}
return true;
});
print_r($b);
You can use array_filter() to filter the array with anonymous function. Then a combination of array_diff() and str_split() to compare each letters of each elements. This works even if the letters on the element of $a array is shuffled
$a = ['abc', 'cde', 'efg', 'hi'];
$b = ['bce', 'ifg', 'hig'];
$b = array_filter($b, function($bElem) use($a) {
foreach ($a as $aElem) {
$diff = array_diff(
str_split($aElem),
str_split($bElem)
);
if (empty($diff)) return false;
}
return true;
});
print_r($b);
As I understood, yuo want to compare start of string from $b with full string from $a
$b = array_udiff($b, $a,
function($x, $y) { return strcmp(substr($x, 0, strlen($y)), $y); });
demo
Loop through the array and look for match. If doesn't match any elements of the array, then push the value.
$a = ['abc', 'cde', 'efg', 'hi'];
$b = ['bce', 'ifg', 'hig'];
$result = $a;
foreach ($b as $bs) {
$flag = true;
foreach ($a as $as) {
if (strpos($bs, $as) !== false) {
$flag = false;
}
}
if($flag==true)
array_push($result, $bs);
}
return $result;

recursively add elements to array and return new array

Let's say I have an array like this:
$my_array = array(1, 2, 3, 4, array(11, 12, 13, 14), 6, 7, 8, array(15, 16, 17, 18), 10);
I want to build a recursive function that returns an array which contains all the even numbers from my_array. I tried something like:
function get_even_numbers($my_array)
{
$even_numbers = array();
foreach($my_array as $my_arr)
{
if(is_array($my_arr)
{
get_even_numbers($my_arr);
foreach($my_arr as $value)
{
if($value % 2 == 0)
{
$even_numbers[] = $value;
}
}
}
}
return even_numbers;
}
But it doesn't works.
Thank you
It's simple:
Check if the input you get into the function is an array.
If it is, that means you have to loop over the values of the array, and call your function (so it is recursive)
Otherwise, just check if the value coming in is even, and add it to an array to return.
That, in PHP, looks like:
function recursive_even( $input) {
$even = array();
if( is_array( $input)) {
foreach( $input as $el) {
$even = array_merge( $even, recursive_even( $el));
}
}
else if( $input % 2 === 0){
$even[] = $input;
}
return $even;
}
Unless it is a thought exercise for your own edification, implementing a recursive function isn't required for this task, which can accomplished instead by using the higher-order, built-in PHP function, array_walk_recursive.
$res = array();
array_walk_recursive($my_array, function($a) use (&$res) { if ($a % 2 == 0) { $res[] = $a; } });
Of course, this could be wrapped in a function:
function get_even_numbers($my_array) {
$res = array();
array_walk_recursive($my_array, function($a) use (&$res) { if ($a % 2 == 0) { $res[] = $a; } });
return $res;
}

Searching for consecutive values in an array

What's the best way to search for consecutive values in an array?
For example, searching for array('a', 'b') in array('x', 'a', 'b', 'c') would yield 1, because the values first appear consecutively at that index.
Haven't tested this, but something like this should do:
function consecutive_values(array $needle, array $haystack) {
$i_max = count($haystack)-count($needle);
$j_max = count($needle);
for($i=0; $i<$i_max; ++$i) {
$match = true;
for($j=0; $j<$j_max; ++$j) {
if($needle[$j]!=$haystack[$i+$j]) {
$match = false;
break;
}
}
if($match) {
return $i;
}
}
return -1;
}
This is probably sub-optimal but is fairly concise:
$needle = array('a', 'b');
$haystack = array('x', 'a', 'b', 'c');
function searchInArray($haystack, $needle)
{
$keys = array_search($haystack, $needle[0]);
foreach ($keys as $key) {
$endPos = $key + count($needle);
for ($i=1; $i<$count($needle); $i++) {
if ($needle[$i] == $haystack[$key + $i]) {
return $key;
}
}
}
return false;
}
This does what you're asking for, it's somewhat specific as all arrays must be non-keyed, and have unique values.
Additionally, in this version the arrays can only contain integer or string values. If you need any NULL, object, float and arrays as well, a part of it needs to be changed from the array_flip() + isset() to array_search().
CodePad / Gist
The relevant part is to compare a slice of the array you search in (here $in) with the array you search for (here $for):
array_slice($in, $pos, $len) === $for
$pos has been looked up earlier for the first value of $for, $len is count($for).

if elements of array 1 exists in array 2

It's a bit like in_array but while in_array checks the presence of one element in an array and returns true and false accordingly, I want to know whether all elements of array1 is part of array2.
Ex:
$array1 = array(3, 30);
$array2 = array(5, 30);
$array3 = array(5, 50);
$array = array(50,7,8,456,1,5,567);
function new_in_array($array1,$array) // false
function new_in_array($array2,$array) // false
function new_in_array($array3,$array) // true
Any idea?
array_intersect will do:
<?php
$first = array('foo', 'bar');
$second = array('foo', 'bar','baz');
var_dump(array_intersect($first, $second) === $first); // True
$first = array('foo', 'bar', 'hello');
$second = array('foo', 'bar','baz');
var_dump(array_intersect($first, $second) === $first); // False
Use array_intersect to intersect those two and check the number of elements in the return array:
$intersect = array_intersect($array1, $array2);
if (count($intersect) == count($array1)) {
// array1 is fully contained in array2
}
Or use array_diff():
function array_contains($haystack, $needles) {
return !count(array_diff($needles, $haystack));
}
array_contains($array2, $array1); // all elements of array1 is part of array2?
You could also use a for loop.
for ($i = 0; $i < sizeof($array1); $i++) {
if (!in_array($array1[$i], $array2)) {
return False;
}
}
return True;

Categories