PHP Array_intersect on multidimensional array with unknown number of keys - php

I'm trying to make advanced search filters in an application that holds resources (people). I've got all the results in 1 multidimensional array. A user of the application can search for the persons Job title, skills, work field and country.
I've already made the part where I look up the people that meet the criteria given by the user. These results are stored in a multidimensional array. If the user is looking for someone with a specific resource with a job title and a specific skill the return value is this:
$realfilters = array(2) {
["resourcesWithJobtitle"]=> array(6) {
[0]=> string(1) "1"
[1]=> string(2) "48"
[2]=> string(2) "88"
}
["resourcesWithSkill"]=> array(9) {
[0]=> string(1) "4"
[1]=> string(1) "8"
[2]=> string(1) "48"
[3]=> string(2) "50"
}
When the user also looks for a work field this is added to the result:
["resourcesWithWorkfield"]=> array(3) {
[0]=> string(2) "48"
[1]=> string(2) "96"
[2]=> string(2) "97"
}
I need to know which resources meet all dimensions of the array so I can display them. (So in this example I need an array with just 1 value: 48). I think I need to use array_intersect but can't seem to get it right.

One of the possible solutions: you may first extract() the $realfilters array values to variables, and then apply the array_intersect() to them. But this solution is applicable only if there are not many possible filters.
Another one and probably the best solution would be to intersect in a loop, something like:
$res_arr = array_shift($realfilters);
foreach($realfilters as $filter){
$res_arr = array_intersect($res_arr, $filter);
}

$intersection = call_user_func_array('array_intersect', $array);
That will give you the elements present in all the sub arrays of $array.
edit-
This above is like a shortcut for writing:
$intersection = array_intersect($array['a'], $array['b'], ...and so on for all elements...);
A loop could be used as well
$intersection = reset($array);
foreach ($array as $subarr) {
$intersection = array_intersect($intersection, $subarr);
}
print_r($intersection);

Related

PHP Multidimensional Array Extract Specific Values Based Upon Key

I'm trying to create an anchor link by extracting specific array values based upon based upon the key. I've tried using a foreach loop inside of a for loop, however that doesn't seem to work.
Based upon the below multidimensional array how can I loop through each subarray to create individual anchor links, such as:
Example:
/* Array Example */
array(3) {
[0]=>
array(2) {
["#attributes"]=>
array(1) {
["id"] => string(1) "2"
}
["name"]=> string(10) "Mark"
}
[1]=>
array(2) {
["#attributes"]=>
array(1) {
["id"]=> string(1) "4"
}
["name"]=> string(8) "John"
}
[2]=>
array(2) {
["#attributes"]=>
array(1) {
["id"]=> string(1) "5"
}
["name"]=> string(10) "Suzy"
}
/* Desired Output */
Mark
John
Suzy
Let's assume the array you posted is the content of a variable called $users. You can walk through it by doing
foreach ($users as $usr)
{
$usr['#attributes']['id'];
$usr['name'];
}
This way, you can go through every node without worrying about the indexes.
You may output the link on each foreach iteration in several ways. A complete example (which allows to use HTML without escaping every special character) could be:
<?php
foreach ($users as $usr)
{ ?>
<?php echo $usr['name']; ?>
<?php } ?>
While it looks complex, with a lot of PHP opening and closing tags, it makes it easier on the markup with almost no performance penalty
You can use either ways: ($array is your array)
$names = array_column($array, 'name');
$ids = array_map(function($ele){return $ele['#attributes']['id'];}, $array);

php sort array without custom function

Here is an extract of my test code and data:-
//Update Array
$civs[1][1]="1";
$civs[1][2]="Inca";
$civs[2][1]="2";
$civs[2][2]="India";
//Sort Array
array_multisort($civs[0][2], SORT_DESC, SORT_STRING,
$civs[0][1], SORT_NUMERIC, SORT_DESC);
Output:-
Warning: array_multisort(): Argument #1 is expected to be an array or
a sort flag in ~/test.php on line 3
array(3) { [1]=> array(2) { [1]=> string(1) "1" [2]=> string(4) "Inca" } [2]=> array(2) { [1]=> string(1) "2" [2]=> string(5) "India" } [0]=> array(2) { [2]=> NULL [1]=> NULL } }
Problem statement
Depending on what the User selects I need to sort the array in PHP either on the 1st (numeric) or 2nd (alphanumeric) element of the 2nd part of the array but can't see how to do that, the various PHP sorts don't seem to allow you to tell it what is to be sorted on, have tried the above code . The PHP Manual for uksort says "If the array you wish to sort needs to be sorted by some non-trivial criteria," well numeric is about as trivial as it gets!
I've been looking at this for a couple of hours now and am sure I must be missing something as all I can see is that I have to write a custom function but surely PHP knows how to do simple sorts based on numeric or text values?
Main question I found was this:- How can I sort arrays and data in PHP? and I also spent a fair bit of time browsing through http://php.net/manual/en/array.sorting.php.
Apologies if I have missed something obvious.

How to get the difference of two arrays

So I have two arrays which looks like this when I do a var_dump :
array(4) {
["DatabinFieldName_1"]=> string(7) "Heading"
["DatabinFieldType_1"]=> string(13) "VARCHAR (255)"
["DatabinFieldName_3"]=> string(11) "DateCreated"
["DatabinFieldType_3"]=> string(8) "DATETIME"
}
array(8) {
["DatabinFieldName_1"]=> string(7) "Heading"
["DatabinFieldType_1"]=> string(13) "VARCHAR (255)"
["DatabinFieldName_2"]=> string(4) "Copy"
["DatabinFieldType_2"]=> string(4) "TEXT"
["DatabinFieldName_3"]=> string(11) "DateCreated"
["DatabinFieldType_3"]=> string(8) "DATETIME"
["DatabinFieldName_4"]=> string(8) "Comments"
["DatabinFieldType_4"]=> string(4) "TEXT"
}
I need to get the difference in a result. Which I have tried using this code.
// Get POST Array
$databinPostArray = $_POST;
// Get Databin Array
$databinObject =json_decode($nbase->getwhere("Databins","ID='".$databinID."' LIMIT 1;",$_SESSION["UserDB"]));
$databinArray= unserialize($databinObject[0]->DatabinArray);
var_dump($databinPostArray);
var_dump($databinArray);
$result = array_diff($databinPostArray, $databinArray);
print_r($result);
Problem is I keep getting Array() back which means its not finding any differences even though there is.
array_diff() returns the elements of the second array which are not in the first one.So the answer to your question is:
$result = array_diff($databinPostArray, $databinArray);
if (couunt($result) == 0) {
$result = array_diff($databinArray, $databinPostArray);
}
This way, the difference will be returned, whether there is more keys in $databinPostArray or in $databinArray.
If what you want is only to check which elements are in $databinArray, but not in $databinPostArray, please do:
$result = array_diff($databinArray, $databinPostArray);
You need to reverse the arguments:
$result = array_diff($databinArray, $databinPostArray);
array_diff returns an array with everything in the first array that isn't in the second array.
If you want to get all the elements that are unique to either array, you can use:
$result = array_diff(array_unique(array_merge($databinArray, $databinPostArray)),
array_intersect($databinArray, $databinPostArray));

PHP shuffle not working like expected on my nested array

I have a nested array of arrays, and I want to shuffle the inner arrays. My code looks like this (simplified):
$a = array(array('banana', 'peach'), array('ding', 'dong'), array('oh snow'));
foreach ($a as &$arr) {
shuffle($arr);
}
var_dump($a);
The var_dump outputs this:
array(3) { [0]=> array(2) { [0]=> string(5) "peach" [1]=> string(6) "banana" } [1]=> array(2) { [0]=> string(4) "ding" [1]=> string(4) "dong" } [2]=> &array(1) { [0]=> string(7) "oh snow" } }
As you can see in the output, the first two subarrays work, but the third subarray is linked by reference in the output...
In my full app, this last array-link causes problems, but rather than working around the issue, I want to fix this shuffle thing...
Cheers!
This has to do with how PHP stores references to array elements. It cannot reference an element of an array, only values. Therefore it has to store the value array('oh snow') in a "slot" of the symbol table, then make $arr and $a[2] a reference to that value.
To fix this, unset($arr) after the loop. That way only a single variable is referencing the value, which will then be made a regular array index again. Unsetting references after a foreach is good practice anyway, since there are many such gotchas.

Modifying an array inside an array

So I need to modify the array in a memcached key-value pair. I need to remove one of the arrays inside the array. An example of what it looks like:
array(2) { [0]=> array(3) { ["username"]=> string(3) "Bob" ["id"]=> string(5) "14537" ["comment"]=> string(4) "cool"} [1]=> array(3) { ["username"]=> string(3) "Tom" ["id"]=> string(5) "14538" ["comment"]=> string(3) "yes"}}
If I know the values of username, id, and comment, how can I delete it? The generic queston: How can I delete array 0?
Considering the answer of doing a foreach loop, I tried
foreach($memcachedarray as $f){
if ($f['id'] == '14537'){
echo key($f);
}
}
But it spits out username
Edit- Ok
I searched some more and found I need to do this:
foreach($memcachedarray as $key => $f){
if ($f['id'] == '14537'){
echo $key;
}
}
That works!
If the Id's are unique across the system then you could use an associative array to store you data then unset the key, otherwise you would want to use a foreach loop to get the array key, then unset that key and recommit your new array back into memcache.

Categories