I am trying to compare a sub-array with the indices with a main array. I tried using array_diff, array_intersect_key, etc, but unable to find the way to proceed, other than using a stupid for loop and doing some old school method.
Okay, let me clarify my question. Say, I have two arrays:
Array
(
[0] => H
[1] => e
[2] => l
[3] => l
[4] => o
[5] => W
[6] => o
[7] => r
[8] => l
[9] => d
[10] => !
)
Array
(
[1] => e
[5] => W
[7] => r
[10] => !
)
The first one is the main array of full string: HelloWorld! and the second one is the sub-array, which has some selected indices and it's values, given by the users. This can also be wrong, for eg:
Array
(
[1] => F
[5] => a
[7] => 6
[10] => t
)
Now, when I pass the first array, it should obviously return true and the next one should return false. Is this possible with the built-in functions using PHP? Thanks in advance.
You should use array_intersect_assoc() if you want to check also if the keys match
if (array_intersect_assoc ($a,$b)==$b) {} else {}
given that $a is the full array and $b the subset to test against.
I think array_intersect_uassoc() is the function you're looking for. It compares based on both keys and values. Here's a quick example:
$array1 = array(0 => 'h', 1 => 'e', 2 => 'l', 3 => 'o');
$array2 = array(0 => 'h', 1 => 'e');
$array3 = array(0 => 'h', 1 => 'z');
var_dump(array_intersect_uassoc($array1, $array2, 'strcasecmp'));
var_dump(array_intersect_uassoc($array1, $array3, 'strcasecmp'));
Output:
array(2) {
[0]=>
string(1) "h"
[1]=>
string(1) "e"
}
array(1) {
[0]=>
string(1) "h"
}
You then compare the size of the second array with the size of the returned array - if they are equal, all matches are right. If the returned array is smaller - there's a mistake in the second array.
Replace strcasecmp() with a callback to your liking and profit :)
Cheers
$array3 = array_diff($array2,$array1); //array2 is checking either present or not in array1
and check array3 is empty. if array3 is empty then matched and if not empty than does not matched.
if (array_diff_assoc($array2, $array1)) {
echo 'array 2 is not an exact subset of array 1';
}
array_diff_assoc returns all elements from $array2 which are not in $array1. So if array 2 is a subset of array 1, the return is an empty array, which evaluates to false, and otherwise a non-empty array, which evaluates to true.
Related
I have the following array structure with master data with thousands of records.
Array
(
[0] => 0,1
[1] => 0,0
[2] => 0,2
[3] => 0,3
[4] => 10,2
)
I have a second array with a smaller subset. Such as
Array
(
[0] => 0,1
[1] => 0,0
)
I would like to find second array in first array in the extact same order of elements present in second array. But rather than doing an intersect I would like to find the key (or keys) from first array as well. I have been wrecking my brain on this...
UPDATED:
The keys are unique . So far example in above array I would like to see output of:
Array2 found in array1 (starting at key 0).
Second Example:
Array
(
[a] => 0,1
[b] => 0,0
[c] => 0,2
[d] => 0,3
[e] => 10,2
)
second array
Array
(
[1] => 0,3
[2] => 10,2
)
expected output:
second array match in array A, starting at key d of array A..
hope that clears it.
The best solution to get matching keys is
$result_array = array_intersect_assoc($array1, $array2);
$result_array_keys = array_keys(array_intersect_assoc($array1, $array2));
print_r($result_array);
print_r($result_array_keys); // this gives matching keys array
I don't understand what is wrong with array_intersect.
As you describe your expected output it seems as array_intersect is perfect.
$a = Array
(
15 => "0,1",
16 => "0,0",
2 => "0,2",
3 => "0,3",
4 => "10,2"
);
$b = Array
(
0 => "0,1",
1 => "0,0"
);
Var_dump(array_intersect($a, $b));
Output:
array(2) {
[15]=> string(3) "0,1"
[16]=> string(3) "0,0"
}
https://3v4l.org/KG1v6
Or if MonkeyZeus is correct maybe this can work for you?
I match array_intersect, then make sure the keys is the same.
$intersect = array_intersect($a, $b);
$keys = array_keys($intersect);
If($keys == array_keys($b)){
Echo "they match";
}else{
Echo "don't match";
}
https://3v4l.org/iiNmd
After OPs edit it seems it is a simple array_intersect that is needed.
https://3v4l.org/gIb10
$intersect = array_intersect($a, $b);
Var_dump($intersect);
Echo "matching keys is: " . Implode(", ", array_keys($intersect));
None of the solutions posted above work. What helped me is to re-structure my array and answer from here: Find array in array, in sequence
I have an array named $arr = array. Some of its keys has value, like this:
$arr['1'] = 'one';
$arr['2'] = 'two';
$arr['3'] = 'three';
Now I initialize that array with another arry, some thing like this:
$arr = array('4' => 'four', '5' => 'five');
But I need to keep the previous values. I mean is, when I print that array, the output will be like this:
echo '<pre>';
print_r($arr);
/* ---- output:
Array
(
[4] => four
[5] => five
)
*/
While I want this output:
Array
(
[1] => one
[2] => two
[3] => three
[4] => four
[5] => five
)
So, How can I take care of old keys (values) after re-initialized?
Here are your options detailed below: array_merge, union (+ operator), array_push, just set the keys directly and make a function that just loops over the array with your own custom rules.
Sample data:
$test1 = array('1'=>'one', '2'=>'two', '3'=>'three', 'stringkey'=>'string');
$test2 = array('3'=>'new three', '4'=>'four', '5'=>'five', 'stringkey'=>'new string');
array_merge (as seen in other answers) will re-index numeric keys (even numeric strings) back to zero and append new numeric indexes to the end. Non numeric string indexes will overwrite the value where the index exists in the former array with the value of the latter array.
$combined = array_merge($test1, $test2);
Result (http://codepad.viper-7.com/c9QiPe):
Array
(
[0] => one
[1] => two
[2] => three
[stringkey] => new string
[3] => new three
[4] => four
[5] => five
)
A union will combine the arrays but both string and numeric keys will be handled the same. New indexes will be added and existing indexes will NOT be overwritten.
$combined = $test1 + $test2;
Result (http://codepad.viper-7.com/8z5g26):
Array
(
[1] => one
[2] => two
[3] => three
[stringkey] => string
[4] => four
[5] => five
)
array_push allows you to append keys to an array. So as long as the new keys are numeric and in sequential order, you can push on to the end of the array. Note though, non-numeric string keys in the latter array will be re-indexed to the highest numeric index in the existing array +1. If there are no numeric keys, this would be zero. You would also need to reference each new value as a separate argument (see arguments two and three below). Also, since the first argument is taken in by reference, it will modify the original array. The other options allow you to combine to a separate array in case you need the original.
array_push($test1, 'four', 'five');
Result (http://codepad.viper-7.com/5b9nvC):
Array
(
[1] => one
[2] => two
[3] => three
[stringkey] => string
[4] => four
[5] => five
)
You could also just set the keys directly.
$test1['4'] = 'four';
$test1['5'] = 'five';
Or even just make a loop and wrap it in a function to handle your custom rules for merging
function custom_array_merge($arr1, $arr2){
//loop over array 2
foreach($arr2 as $k=>$v){
//if key exists in array 1
if(array_key_exists($arr1, $k)){
//do something special for when key exists
} else {
//do something special for when key doesn't exists
$arr1[$k] = $v;
}
}
return $arr1;
}
The function could be expanded to use stuff like func_get_args to allow any number of arguments.
I'm sure there are also more "hacky" ways to do it using stuff like array_
splice or other array functions. However, IMO, I would avoid them just to keep the code a little more clear about what you are doing.
use array_merge:
$arr = array_merge($arr, array('4' => 'four', '5' => 'five'));
Well, as per the comments (which are correct) this will reindex the array, another solution to avoid that would be to do as follows:
array_push($arr, "four", "five");
But this would not work if you have different keys, like strings that are not masked numbers.
Another way is to use + in order to merge them maintaining keys:
$arr['1'] = 'one';
$arr['2'] = 'two';
$arr['3'] = 'three';
$arr2 = array('4' => 'four', '5' => 'five');
$arr = $arr + $arr2;
Another way to do it, and keeps the keys of the array, is using array_replace.
$arr['1'] = 'one';
$arr['2'] = 'two';
$arr['3'] = 'three';
print_r(array_replace($arr, array('4' => 'four', '5' => 'five')));
Output:
Array
(
[1] => one
[2] => two
[3] => three
[4] => four
[5] => five
)
I have an array with 3 values:
$b = array('A','B','C');
This is what the original array looks like:
Array ( [0] => A [1] => B [2] => C )
I would like to insert a specific value(For example, the letter 'X') at the position between the first and second key, and then shift all the values following it down one. So in effect it would become the 2nd value, the 2nd would become the 3rd, and the 3rd would become the 4th.
This is what the array should look like afterward:
Array ( [0] => A [1] => X [2] => B [3] => C )
How do I insert a value in between two keys in an array using php?
array_splice() is your friend:
$arr = array('A','B','C');
array_splice($arr, 1, 0, array('X'));
// $arr is now array('A','X','B','C')
This function manipulates arrays and is usually used to truncate an array. However, if you "tell it" to delete zero items ($length == 0), you can insert one or more items at the specified index.
Note that the value(s) to be inserted have to be passed in an array.
There is a way without the use of array_splice. It is simpler, however, more dirty.
Here is your code:
$arr = array('A', 'B', 'C');
$arr['1.5'] = 'X'; // '1.5' should be a string
ksort($arr);
The output:
Array
(
[0] => A
[1] => B
[1.5] => X
[2] => C
)
I have an array in PHP that looks like
Array ( [123654] => Array ( [0] => 123456789123456789 [1] => 1 [2] => 06/24/2011 [3] => 06/24/2012 [4] => 12355.44 [5] => 55321.55 ) )
I know in javascript I could access the data I need by doing array[0][0], how would I go about doing this in PHP. It is the 123456789123456789 value that I'm looking at getting.
Try this
array_slice($array, 0, 1);
http://php.net/array_slice
If you don't know the exact keys, you could do something like this:
$a = array_values($my_array);
$b = array_values($a[0]);
echo $b[0];
array_values replaces the keys by simple numbers from 0 to n-1 (where n is the count of values), by that you can access your desired value with the indexes [0][0]. See more here
http://codepad.org/YXu6884R
Here you go. See above for proof. The methodology from #azat is not explicit enough and is prone to risk if the elements of the array or sub array are re-arranged or if the key value for the super array changes.
$my_array = array( 123654 => array( 0 => '123456789123456789', 1 => '1', 2 => '06/24/2011', 3 => '06/24/2012', 4 => '12355.44', 5 => '55321.55' ) );
echo $my_array['123654'][0];
Try
$first = array_shift(array_values($array));
http://php.net/manual/en/function.array-shift.php
Anyone have any idea why shuffle() would only return 1 item?
when using:
$array2 = shuffle($array1);
with the following array($array1):
Array
(
[0] => 1
[1] => 5
[2] => 6
[3] => 7
[4] => 8
[5] => 10
[6] => 11
[7] => 12
[8] => 13
[9] => 14
)
The output of:
print_r($array2);
is simply: 1
Any idea as to why it would not only not shuffle the array, but knock off the remaining 9 items in the array?
thanks!
shuffle() shuffles the array in place, and returns true if it succeeded. If you want $array2 to be a shuffled version of $array1, first make it a copy of $array1 and then call shuffle($array2);
See the docs: shuffle
shuffle changes the original array. So in your case the shuffled array is $array1.
$array2 is simply a boolean value. The function returns true or false.
Please read a function description before use http://php.net/shuffle
it may work other than you expect.
$array2 = $array1;
shuffle($array2);
print_r($array2);