PHP Multidimensional array searching for combinations of values in array - php

I have a multidimensional array:
$array =
Array (
[0] => Array ( [id] => 2 [zoneId] => 2 [buildingId] => 2 [typeId] => 2 )
[1] => Array ( [id] => 4 [zoneId] => 2 [buildingId] => 2 [typeId] => 1 )
[2] => Array ( [id] => 6 [zoneId] => 6 [buildingId] => 17 [typeId] => 2 ) )
And I would like to search if the combination of, for example, [buildingId] => 2, [typeId] => 2 exists is array 0, 1 or 2.
I tried the following:
$keyType = array_search(2, array_column($array, 'typeId'));
$keyBuilding = array_search(2, array_column($array, 'buildingId'));
if(is_numeric($keyType)&&is_numeric($keyBuilding)){
echo 'Combination does exists'
}
This works, but gives also a false positive if I would search for [buildingId] => 17, [typeId] => 1. How can I solve this?
edit
I would also like to know if a combination is not in the array, how can I arrange that?
if($result == false){
echo 'does not exists';
}

You can try this code:
$keyTypeExistsAndHaveSameValue = isset($array['typeId']) && $array['typeId'] === 2;
$keyBuildingExistsAndHaveSameValue = isset($array['buildingId']) && $array['buildingId'] === 2;
if($keyTypeExistsAndHaveSameValue && $keyBuildingExistsAndHaveSameValue){
echo 'Combination does exists'
}
This code check if typeId & buildingId keys exist but it also check if its values are 2 and 2.

$buildingId = 2;
$typeId = 2;
$result = false;
foreach ($array as $key => $val) {
if ($val['buildingId'] == $buildingId && $val['typeId'] == $typeId) {
$result = $key; // If you want the key in the array
$result = $val; // If you want directly the entry you're looking for
break; // So that you don't iterate through the whole array while you already have your reuslt
}
}

I think what you need is this
$keyType = array_search(1, array_column($array, 'typeId'));
$keyBuilding = array_search(17, array_column($array, 'buildingId'));
if(is_numeric($keyType)||is_numeric($keyBuilding)){
echo 'Combination does exists';
}
Now here you need or operator instead of and operator because you want either typeid = 1 exists or building id = 17 exists.
If I have understand your question correctly then you are trying to do something like this, right ?
Hope this helps!

You would need to do a foreach loop to get the actual array number, the other solution don't seems to answer what you're looking for, which is to get the index number.
I would like to search if the combination of, for example, [buildingId] => 2, [typeId] => 2 exists is array 0, 1 or 2.
EDIT: This code is just sample code to show how you would get the array index number, in a production environment you would save the matching arrays, comparison figures are not hard coded, etc...
$array = array(array('id' => 2, 'zoneId' => 2, 'buildingId' => 2, 'typeId' => 2),
array('id' => 4, 'zoneId' => 2, 'buildingId' => 2, 'typeId' => 2),
array('id' => 6, 'zoneId' => 6, 'buildingId' => 17, 'typeId' => 2));
foreach ($array as $building => $building_details)
{
if ($building_details['buildingId'] === 2 && $building_details['typeId'] === 2)
{
echo 'Array number ' . $building . ' matches criteria<br>';
}
}
Output:
Array number 0 matches criteria
Array number 1 matches criteria
You can view this snippet online here.

Related

How to create a new array using of another array keys?

Is it possible to create a new array from the keys of another like following?
it is a dynamic array chk_values are dynamically changed depends on condition
Array
(
[actBtn] => update
[chkCount] => 5
[chk_1] => 2
[chk_2] => 3
[chk_3] => 2
[chk_4] => 3
[chk_5] => 3
)
and i want array like this for update database
$chckpoint = Array(
[chk_1] => 2
[chk_2] => 3
[chk_3] => 2
[chk_4] => 3
[chk_5] => 3)
Simply process the original array and only move to the new array where the key starts with chk_
$in = ['actBtn' => 'update',
'chkCount' => 5,
'chk_1' => 2,
'chk_2' => 3,
'chk_3' => 2,
'chk_4' => 3,
'chk_5' => 3
];
foreach($in as $k=>$v){
if ( strpos($k,'chk_') !== false ){ $chckpoint[$k] = $v; }
}
print_r($chckpoint);
RESULT
Array
(
[chk_1] => 2
[chk_2] => 3
[chk_3] => 2
[chk_4] => 3
[chk_5] => 3
)
You can simply take the input array and check for all keys beginning with chk_. If the key matches, take it to the new array.
$chckpoint = [];
foreach($input as $key => $value)
{
if(substr($key, 0, 4) == 'chk_') $chkpoint[$key] = $value;
}

How to get data from variable array length?

I have this code:
$ItemID = 'a62442e2-ca1f-4fd1-b80d-0d0dc511758e';
$GET_FreeTextFields = new \Picqer\Financials\Exact\ItemExtraField($connection);
$FreeTextFields = $GET_FreeTextFields->filter("ItemID eq guid'$ItemID'", '', '' );
$FreeTextFields01 = array();
$FreeTextFields02 = array();
foreach($FreeTextFields as $GET_FreeTextFields){
$FreeTextFields01[] = $GET_FreeTextFields->Value;
$FreeTextFields02[] = $GET_FreeTextFields->Number;
}
print_r($FreeTextFields01);
print_r($FreeTextFields02);
This outputs:
Value Array
(
[0] => 390
[1] => 804715
[2] => WW001
[3] => WHT/WHT/WHT
[4] => 39/42
[5] => 804715 WW00139/42
[6] => 3pk Quarter Socks
)
Numbers Array
(
[0] => 3
[1] => 4
[2] => 5
[3] => 6
[4] => 7
[5] => 8
[6] => 10
)
What this needs to output:
What i want if i use the first output so with 6 values in the array:
$FreeTextField01 = null
$FreeTextField02 = null
$FreeTextField03 = 390
$FreeTextField04 = 804715
$FreeTextField05 = WW001
$FreeTextField06 = WHT/WHT/WHT
$FreeTextField07 = 39/42
$FreeTextField08 = 804715 WW00139/42
$FreeTextField09 = null
$FreeTextField10 = 3pk Quarter Socks
But with other $ItemID, it can also output:
Value Array
(
[0] => 10100153
[1] => 2007
[2] => 350
[3] => 804082
[4] => WW006
[5] => WHT/NNY/OXGM
[6] => 35/38
[7] => 804082 WW00635/38
[8] => 0,00138857
[9] => Champion 3pk Quarter Socks
)
Numbers Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
[5] => 6
[6] => 7
[7] => 8
[8] => 9
[9] => 10
)
What i want is that if a variable is not in the numbers list so 1-10, setting it to empty, and if the numbers is in the numbers array setting that number to the corresponding value variable. For example the number at [0] is 1 then set the variable $FreeTextField1 to $NumbersArray[0]->Value.
I keep making all kinds off loops but i just get stuck at the fact that the array length changes so that [6] can be the number 10 at one $itemID, but at another $ItemID, the number can be 6.
I tried researching this but I don't even know what I have to type in google to find this problem, that's why I'm describing it here.
edit i tried describing it a second time:
Yeah I'm having problems describing what i want, so let me try again. I get two arrays as output one with numbers that correspond with place it stands, as example you have FreeTextField0 thru FreeTextField10. What i tried to do is if (Numbers[0] == 0){ $FreeTextField0 = Value[0]}, but then I get the problem that Numbers[0] can be 3 or something else because if FreeTextField1 is empty i don't get a null value but nothing.
What i want if i use the first output so with 6 values in the array:
$FreeTextField01 = null
$FreeTextField02 = null
$FreeTextField03 = 390
$FreeTextField04 = 804715
$FreeTextField05 = WW001
$FreeTextField06 = WHT/WHT/WHT
$FreeTextField07 = 39/42
$FreeTextField08 = 804715 WW00139/42
$FreeTextField09 = null
$FreeTextField10 = 3pk Quarter Socks
I think this is what you're after but I have to say that I think you're barking up the wrong tree here. You really should not dynamically create variables in your script. To me, it is a serious code-smell and I think you should evaluate your design here.
http://sandbox.onlinephpfunctions.com/code/b245a0218ce174e68508139872f394def5409b05
<?php
// Test case
$values = [
'390',
'804715',
'WW001',
'WHT/WHT/WHT',
'39/42',
'804715 WW00139/42',
'3pk Quarter Socks'
];
$numbers = [3, 4, 5, 6, 7, 8, 10];
// Flip the $numbers array and then use the keys to find the corresponding values in the $values array
$intersection = array_unique(array_intersect_key($values, array_flip($numbers)));
// Fill in the missing keys and use `null` as the value
$output = $intersection + array_fill_keys(range(1,10), null);
// Sort the final output by the keys
ksort($output);
// Format the keys to match FreeTextField{00}
$output = array_combine(
array_map(function($k){ return 'FreeTextField'.str_pad($k, 2, '0', STR_PAD_LEFT); }, array_keys($output)),
$output
);
// Use the extract function to bring all those array keys + values into the symbol table.
// You can now use $FreeTextField01 - $FreeTextField10
extract($output);
var_dump($output);
UPDATE
http://sandbox.onlinephpfunctions.com/code/244c4f1ed45db398c48b8330c402b375eb358446
<?php
// Test case
$input = [
['Value' => '390', 'Number' => 3],
['Value' => '804715', 'Number' => 4],
['Value' => 'WW001', 'Number' => 5],
['Value' => 'WHT/WHT/WHT', 'Number' => 6],
['Value' => '39/42', 'Number' => 7],
['Value' => '804715 WW00139/42', 'Number' => 8],
['Value' => '3pk Quarter Socks', 'Number' => 10],
];
$intersection = [];
foreach ($input as $config) {
$value = $config['Value'];
$number = $config['Number'];
$intersection[$number] = $value;
}
// Fill in the missing keys and use `null` as the value
$output = $intersection + array_fill_keys(range(1,10), null);
// Sort the final output by the keys
ksort($output);
// Format the keys to match FreeTextField{00}
$output = array_combine(
array_map(function($k){ return 'FreeTextField'.str_pad($k, 2, '0', STR_PAD_LEFT); }, array_keys($output)),
$output
);
// Use the extract function to bring all those array keys + values into the symbol table.
// You can now use $FreeTextField01 - $FreeTextField10
extract($output);
var_dump($output);
Use ${$var}
If you want to see a doc about this type of var you can see it here:
http://php.net/manual/en/language.variables.variable.php

How to return array as multi dimensional array?

I i'm developing php application. I have used Google Chart API for display charts.
I have select and returned necessary data for chart.
I got following array as my output.
print_r($output);
//Out put
Array
(
[0] => Array
(
[month] => April
[sec_id] => 2
[sec_name] => Commerce
[count] => 1
)
[1] => Array
(
[month] => June
[sec_id] => 2
[sec_name] => Commerce
[count] => 3
)
[2] => Array
(
[month] => July
[sec_id] => 2
[sec_name] => Commerce
[count] => 1
)
[3] => Array
(
[month] => August
[sec_id] => 4
[sec_name] => Science
[count] => 3
)
[4] => Array
(
[month] => August
[sec_id] => 3
[sec_name] => Maths
[count] => 2
)
[5] => Array
(
[month] => August
[sec_id] => 1
[sec_name] => Art
[count] => 2
)
[6] => Array
(
[month] => August
[sec_id] => 2
[sec_name] => Commerce
[count] => 2
)
)
print_r(json_encode($output)); // return above array as output
I request above data using ajax ( data type is JSON)
I want to return data as bellow to generate google chart.
[
['Month', 'Art', 'Commerce', 'Maths', 'Sience'],
['April', '', 2, '', ''],
['June', '', 3, '', ''],
['July', '', 1, '', ''],
['August', 2, 2, 3, 3]
]
I tried this this code
$output = array();
$output[0] = array('Month', 'Art', 'Commerce', 'Maths', 'Science');
foreach($records as $key=> $record){
$art =''; $commerce =''; $maths=''; $science='';
if($record['sec_id'] == 1){
$art = $record['count'];
}else if($record['sec_id'] == 2){
$commerce = $record['count'];
}else if($record['sec_id'] == 3){
$maths = $record['count'];
}else if($record['sec_id'] == 4){
$science = $record['count'];
}
$output[++$key] = array(0 => $record['month'], 1 => $art, 2 => $commerce, 3 => $maths, 4 => $science);
}
function super_unique($array){
$result = array_map("unserialize", array_unique(array_map("serialize", $array)));
foreach ($result as $key => $value){
if ( is_array($value)){
$result[$key] = super_unique($value);
}
}
return $result;
}
$output = super_unique($output);
Out put was
[["Month","Art","Commerce","Maths","Science"],["April","","1"],["June","","3"],["July","","1"],{"0":"August","1":"","4":"3"},{"0":"August","1":"","3":"2"},["August","2",""],["August","","2"]]
This is pretty straightforward to loop through and reorganize, particularly since your sec_ids match up nicely with the array indices.
Example:
$temp = array();
$output = array(
array('Month', 'Art', 'Commerce', 'Maths', 'Science')
);
foreach ($records as $record) {
$month = $record["month"];
$sec_id = $record["sec_id"];
$count = $record["count"];
if (!isset($temp[$month])) {
$temp[$month] = array_fill(0, 5, '');
}
$temp[$month][0] = $month;
$temp[$month][$sec_id] += $count;
}
$output = array_merge($output, array_values($temp));
echo json_encode($output);
Output:
[["Month","Art","Commerce","Maths","Science"],["April","",2,"",""],["June","",3,"",""],["July","",1,"",""],["August",2,2,2,3]]
Let's rethink your algorithm. As you go through each element in records, we need to ask two things: what data are we pulling out and what do we want to do with it?
The first question is simple: we're just pulling out the value 'count'.
The second question is going to determine our algorithm. What we want to do is take that 'count' value, and stick it a particular spot in our ourpur array.
Looking at the output array as a table, we can see that the desired position of 'count' is determined by the 'month' field (which determines the row) and by the 'sec_id'/'sec_name' fields (which determine the column). So what you want your loop to look like is this...
foreach($records as $record)
{
$output[$record['month']][$record['sec_id']] = $record['count']
}
The first caveat to this is that for each unique month, you do still need to create and initialize the sub-array, and you must do it only once. So, the loop becomes.
foreach($records as $record)
{
if(!is_array($output[$record['month']]))
$output[$record['month']] = array(0 => $record['month'], 1 => '', 2 => '', 3 => '', 4 => '');
$output[$record['month']][$record['sec_id']] = $record['count']
}
Finally, we used the actual month name as the keys in the top-level array. To comply with the numeric-only keys specified in your desired output, we can ditch those keys with the following piece of code.
$output = array_values($output)
If I'm right in thinking you were trying to use super_unique() to combine rows with the same month, that's not what it was doing at all. Firstly, array_unique() doesn't combine rows, it eliminates duplicates. Since you were comparing serialized rows, rather than just looking at the month field, none of your rows were duplicates, so that function was doing nothing. Furthermore, since several of your array fields were set to '', the serialize/unserialize process was actually causing those fields to get dropped, which is why you were ending up with sub-arrays of less than five elements, and with associative keys.

Using PHP to extract key from value in an array

I have a PHP array that prints the following information:
Array (
[0] => 23
[1] => 34
[2] => 35
[3] => 36
[4] => 37
[5] => 38
..<snip>..
)
I have the value and would like to cross reference it with the array to return a key. For instance, if I have a variable $value = 34 I would want to run a PHP function to return the key, which in this case is 1.
To be more specific, the array is stored in variable $pages and the value is stored in variable $nextID. I tried using array_search with no luck:
How do I go about this?
array_search is exactly what you're looking for. I'm not sure how you had problems with it.
$arr = [
5,
10,
15,
20
];
$value = 15;
echo array_search($value, $arr); // 2
You could use foreach() like that:
<?php
$arr = array('a' => 1, 'b' => 2, 'c' => 3, 'd' => 4);
function mySearch($array, $search){
foreach($array as $key => $value){
if($value == $search){
return $key;
}
}
}
echo mySearch($arr, 3);
?>

Count number of different strings?

I have an array that looks like
Array
(
[1] => Array
(
[0] => Date
[1] => Action
)
[2] => Array
(
[0] => 2011-01-22 11:23:19
[1] => SHARE_TWEET
)
[3] => Array
(
[0] => 2011-01-22 11:23:19
[1] => SHARE_FACEBOOK
)
and many other different values (about 10), what I want to do is I want to count the number of times a string is in the array. I was going to use array_count_values but it doesn't count multidimensional arrays.
Any other options?
This could be done by first flattening the array, and then using array_count_values() on it:
For flattening, here is the trick:
$array = call_user_func_array('array_merge', $arrays);
And then:
$counts = array_count_values($array);
Output:
array (
'Date' => 1,
'Action' => 1,
'2011-01-22 11:23:19' => 2,
'SHARE_TWEET' => 1,
'SHARE_FACEBOOK' => 1,
)
Full code:
$array = call_user_func_array('array_merge', $arrays);
var_export(array_count_values($array));
Any time you're dealing with arrays, especially with loops in PHP I can't string enough suggest you look at the array documentation, You'd be suprised how quickly you realise most of the loops in your code is unnecessary. PHP has a built in function to achieve what you're after called array_walk_recursive. And since you're using PHP5 you can use closures rather that create_function (which can be very troublesome, especially to debug, and can't be optimised by the PHP interpreter afik)
$strings = array();
array_walk_recursive($arr, function($value, $key) use (&$strings) {
$strings[$value] = isset($strings[$value]) ? $strings[$value]+1 : 1;
});
I know, unary statements aren't always clear, but this one is simple enough, but feel free to expand out the if statement.
The result of the above is:
print_r($strings);
Array
(
[Date] => 1,
[Action] => 1,
[2011-01-22 11:23:19] => 2,
[SHARE_TWEET] => 1,
[SHARE_FACEBOOK] => 1,
)
Pseudo Code
$inputArray = // your array as in the example above
foreach ($inputArray as $key => $value) {
$result[$value[1]] = $result[$value[1]] + 1;
}
var_dump($result);
Here is a way to do the job:
$arr = Array (
1 => Array (
0 => 'Date',
1 => 'Action'
),
2 => Array (
0 => '2011-01-22 11:23:19',
1 => 'SHARE_TWEET'
),
3 => Array (
0 => '2011-01-22 11:23:19',
1 => 'SHARE_FACEBOOK'
)
);
$result = array();
function count_array($arr) {
global $result;
foreach($arr as $k => $v) {
if (is_array($v)) {
count_array($v);
} else {
if (isset($result[$v])) {
$result[$v]++;
} else {
$result[$v] = 1;
}
}
}
}
count_array($arr);
print_r($result);
output:
Array
(
[Date] => 1
[Action] => 1
[2011-01-22 11:23:19] => 2
[SHARE_TWEET] => 1
[SHARE_FACEBOOK] => 1
)

Categories