Find the longest matching string in an array - php

I have an array of hierarchically arranged identifiers (SNMP sysObjectIDs), that I'd like to match against in order to find the closest match.
For example, if my array contains :
.1.3.6.1.4.1.207 = alliedware
.1.3.6.1.4.1.207.1.14 = alliedwareplus
.1.3.6.1.4.1.207.1.4.126 = allied-radlan
.1.3.6.1.4.1.207.1.4.125 = allied-radlan
And I search for
.1.3.6.1.4.1.207.1.14.69
I would like it to return the alliedwareplus entry.
If I search for
.1.3.6.1.4.1.207.1.4
It should return the alliedware entry.
Basically I just want to return the longest match starting from the beginning of the string.
Thanks in advance!

This worked for me and returns the correct test results based on your description.
function find_match($data,$search) {
$keys = array_keys($data);
usort($keys,function($a,$b){
return strlen($b)-strlen($a);
});
foreach($keys as $key){
if (substr($search,0,strlen($key)) == $key)
return $data[$key];
}
}
$data = array(
'.1.3.6.1.4.1.207' => 'alliedware',
'.1.3.6.1.4.1.207.1.14' => 'alliedwareplus',
'.1.3.6.1.4.1.207.1.4.126' => 'allied-radlan',
'.1.3.6.1.4.1.207.1.4.125' => 'allied-radlan',
);
find_match($data,'.1.3.6.1.4.1.207.1.14.69'); // => 'alliedwareplus'
find_match($data,'.1.3.6.1.4.1.207.1.4'); // => 'alliedware'

Sort the array by the number of components in the object ID, from high to low.
Loop through the array, testing whether the object ID in the array is a prefix of the input object ID.
When you find a match like this, break out of the loop.
All these steps will probably be easiest if you first convert all the object IDs to an array:
$objid_arr = explode('.', $objid);

Related

PHP check if array contains any key other than some whitelisted

I would like to check all keys of a global GET array and do something, if it contains keys, other than some whitelisted ones from an array.
Let's say the current url is:
.../index.php?randomekey1=valueX&randomkey2=valueY&acceptedkey1=valueZ&randomkey3=valueA&acceptedkey2=valueB
Just for better visualization:
These GET parameters are all available in the global GET variable which looks something like this:
$GET = array(
"randomekey1" => "valueX",
"randomkey2" => "valueY",
"acceptedkey1" => "valueZ",
"randomkey3" => "valueA",
"acceptedkey2" => "valueB"
);
The keys I accept and want to let pass, I put into an array too:
$whitelist = array(
"acceptedkey1",
"acceptedkey2",
"acceptedkey3",
);
Now I want to check whether $GET contains any key other than the whitelisted. So in the URL example from above it should return "true", because there are keys in the $GET array which aren't in the whitelist.
Not only the existence of such an unknown (none whitelisted) key should trigger a true, but please also its emptyness!
Another example would be the following url:
.../index.php?acceptedkey1=valueZ&acceptedkey3=valueB
This should return false, because no other key other than the ones in the whitelist were found.
Unfortunately I was not able to find any modification of the in_array function or array_search which would fit these requirements, because as far as I know these functions are only looking for something specific, whereas in my requirements I am also looking for something specific (the whitelist keys), but at the same tme I have to check if some unknown keys exist.
Thank you.
It seems you want to determine whether an array contains keys that don't exist in a whitelist.
One way to find the difference between arrays is to use array_diff():
array_diff ( array $array1 , array $array2 [, array $... ] ) : array
Returns an array containing all the entries from array1 that are not present in any of the other arrays.
So, it can be used to return all keys from the URL that are not present in the whitelist:
$extrasExist = !empty( array_diff( array_keys($GET), $whitelist ) );
var_dump($extrasExist);
Here's a demonstration:
$get1 = array(
"randomekey1" => "valueX",
"randomkey2" => "valueY",
"acceptedkey1" => "valueZ",
"randomkey3" => "valueA",
"acceptedkey2" => "valueB"
);
$get2 = array(
"acceptedkey1" => "valueZ",
"acceptedkey2" => "valueB"
);
$whitelist = array(
"acceptedkey1",
"acceptedkey2",
"acceptedkey3"
);
$extrasExist = !empty(array_diff(array_keys($get1),$whitelist));
var_dump($extrasExist);
$extrasExist = !empty(array_diff(array_keys($get2),$whitelist));
var_dump($extrasExist);
bool(true)
bool(false)
Everything in PHP doesn't have to be all "lets find function that does exactly what I'm looking for". Just do a simple foreach loop, which can accomplish what you're looking for:
function clear_filter() {
$whitelist = array( "project", "table_name", "filterDates", );
foreach ($_GET as $gkey => $gval) {
if (!in_array($gkey, $whitelist)) {
return false;
}
}
return true;
}
You can also write it more simply, with one foreach loop like below:
function isValid() {
// Copy the array
$temp = $_GET;
// Loop through the array, and remove any whitelisted elements
foreach ($whitelist as $wkey) {
unset($temp[$wkey]);
}
// If count($temp) > 0, there are non whitelisted entries in the array.
return count($temp) === 0;
}
You can use the following function.
$check = checkWhitliest( $_GET, $whitelist ) );
var_dump ($check );
You can call the above function as
function checkWhitliest( $array, $whitelist ) {
$allKeys = array_keys ( $array); //Get all Keys from the array.
$diff = array_diff( $allKeys, $whitelist); //Get the values which are not in whitelist.
if( count ( $diff ) > 0 ) { //If the count is greater than 0, then there are certain extra kesy in $_GET
return true;
}
return false;
}
There are only two techniques that I would recommend for this task and both make key comparisons for performance reasons. Using array_diff() or in_array() will always be slower than array_diff_key() and isset(), respectively, because of how PHP treats arrays as hash maps.
If you don't mind iterating the entire $GET array (because its data is relatively small), then you can concisely flip the whitelist array and check for any key differences.
var_export(
(bool)array_diff_key($GET, array_flip($whitelist))
);
If performance is more important than code brevity, then you should craft a technique that uses a conditional break or return as soon as a non-whitelisted key is encountered -- this avoids doing pointless iterations after the outcome is decided.
$hasNotWhitelisted = false;
$lookup = array_flip($whitelist);
foreach ($GET as $key => $value) {
if (isset($lookup[$key])) {
$hasNotWhitelisted = true;
break;
}
}
var_export($hasNotWhitelisted);
Or
function hasNotWhitelisted($array, $whitelist): bool {
$lookup = array_flip($whitelist);
foreach ($array as $key => $value) {
if (isset($lookup[$key])) {
return true;
}
}
return false;
}
var_export(hasNotWhitelisted($GET, $whitelist));
All of the above techniques deliver a true result for the sample data. Demo of all three snippets.

Joining Two Arrays Together and Counting Unique Id by using Laravel, PHP

I have those two arrays that I added to attachments.
"PartnerAffiliateCodeId" from first array and "Id" from second array is our primary key.
"UserAction" must be counted for every unique "PartnerAffiliateCodeId" so in our case it is 5.
Normally I think this must be done by SQL but unfortunately this is a API method that I am receiving so I have to handle it by PHP.
Any ideas about how I can make such join with PHP using these two arrays?
I'm unclear on exactly what you're trying to get at with UserAction, but you could try something like this:
//$array1 = the first array
//$array2 = the second array
array_push($array_1, array(
"DateTime" => "",
"HttpReferer" => "",
"Id" => count($array1),
"PartnerAffiliateCodeId" => $array2["Id"],
"UserAction" => "Click"
));
It sounds like you want to match the ID key to the PartnerAffiliateCodeId in your returned data set.
Without knowing your setup, or bothinging with total optimization here a workable solution which will give you some direction.
function selectPartnerWhere($id=null; $from=array())
{
$codes = array();
foreach($from as $k => $p)
{
if($id == $p['PartnerAffiliateCodeId'])
{
return $from[$k];
}
}
return array();
}
$theData = //your array above
$thePartner = //your partner above
$partnerData = selectPartnerWhere($thePartner['Id'], $theData);

choosing a specific value from a series of values array php

I have an array which looks like this:
I need to have the array in this format for use later in the script.
//this is only 1 values set there are others that are returned.
Array
(
[DealerName] => Auto Bavaria Midrand MINI
[CustomersCounted] => 16
[Satisfied_Y] => 10
[Satisfied_N] => 6
[InterviewDate] => 2012-01-13
)
I have called the array $customerSatisfactionRatings which I loop through.
foreach($customerSatisfactionRatings as $customerSatisfactionRating) {
$content .= $customerSatisfactionRating';
}
This returns the correct values into the content variable.
What I am interested in is creating a string from the [Satisfied_Y] key.
an example of what I need is $content = '10,5,15,7,8,9,0,3';
I know how to make the string, but not how to extract only the [Satisfied_Y] key.
This makes me sad.
You use a mapping function to pull every Satisfied_Y column out of each $customerSatisfactionRatings item and then you join the results together:
$content = join(',', array_map(function($item) {
return $item['Satisfied_Y'];
}, $customerSatisfactionRatings));
This assumes that each item in $customerSatisfactionRatings is an array as described in your question.
See also: array_map()
I think it will work. Try this,
$satisfyY = array();
foreach($customerSatisfactionRatings as $customerSatisfactionRating) {
$content .= $customerSatisfactionRating;
$satisfyY = $customerSatisfactionRating['Satisfied_Y'];
}
Then implode it to make a string.
$sat_Y = implode(",", $satisfyY);
foreach($customerSatisfactionRatings as $temp)
if (isset($temp['Satisfied_Y']))
{
if (isset($content)) $content.=','.$temp['Satisfied_Y'];
else $content=$temp['Satisfied_Y'];
}

PHP search array using wildcard?

Assume that i have the following arrays containing:
Array (
[0] => 099/3274-6974
[1] => 099/12-365898
[2] => 001/323-9139
[3] => 002/3274-6974
[4] => 000/3623-8888
[5] => 001/323-9139
[6] => www.somesite.com
)
Where:
Values that starts with 000/, 002/ and 001/ represents mobile (cell) phone numbers
Values that starts with 099/ represents telephone (fixed) numbers
Vales that starts with www. represents web sites
I need to convert given array into 3 new arrays, each containing proper information, like arrayTelephone, arrayMobile, arraySite.
Function in_array works only if i know whole value of key in the given array, which is not my case.
Create the three empty arrays, loop through the source array with foreach, inspect each value (regexp is nice for this) and add the items to their respective arrays.
Loop through all the items and sort them into the appropriate arrays based on the first 4 characters.
$arrayTelephone = array();
$arrayMobile = array();
$arraySite = array();
foreach($data as $item) {
switch(substr($item, 0, 4)) {
case '000/':
case '001/':
case '002/':
$arrayMobile[] = $item;
break;
case '099/':
$arrayTelephone[] = $item;
break;
case 'www.':
$arraySite[] = $item;
break;
}
}
You can loop over the array and push the value to the correct new array based on your criteria. Example:
<?php
$fixed_array = array();
foreach ($data_array as $data) {
if (strpos($data, '099') === 0) {
$fixed_array[] = $data;
}
if ....
}
Yes i actually wrote the full code with preg_match but after reading some comments i accept that its better to show the way.
You will create three different arrays named arrayTelephone, arrayMobile, arraySite.
than you will search though your first array with foreach or for loop. Compare your current loop value with your criteria and push the value to one of the convenient new arrays (arrayTelephone, arrayMobile, arraySite) after pushing just continue your loop with "continue" statement.
You can find the solution by looking add the Perfect PHP Guide

Change the array KEY to a value from sub array

This is the set of result from my database
print_r($plan);
Array
(
[0] => Array
(
[id] => 2
[subscr_unit] => D
[subscr_period] =>
[subscr_fee] =>
)
[1] => Array
(
[id] => 3
[subscr_unit] => M,Y
[subscr_period] => 1,1
[subscr_fee] => 90,1000
)
[2] => Array
(
[id] => 32
[subscr_unit] => M,Y
[subscr_period] => 1,1
[subscr_fee] => 150,1500
)
)
How can I change the $plan[0] to $plan[value_of_id]
Thank You.
This won't do it in-place, but:
$new_plan = array();
foreach ($plan as $item)
{
$new_plan[$item['id']] = $item;
}
This may be a bit late but I've been looking for a solution to the same problem. But since all of the other answers involve loops and are too complicated imho, I've been trying some stuff myself.
The outcome
$items = array_combine(array_column($items, 'id'), $items);
It's as simple as that.
You could also use array_reduce which is generally used for, well, reducing an array. That said it can be used to achieve an array format like you want by simple returning the same items as in the input array but with the required keys.
// Note: Uses anonymous function syntax only available as of PHP 5.3.0
// Could use create_function() or callback to a named function
$plan = array_reduce($plan, function($reduced, $current) {
$reduced[$current['id']] = $current;
return $reduced;
});
Note however, if the paragraph above did not make it clear, this approach is overkill for your individual requirements as outlined in the question. It might prove useful however to readers looking to do a little more with the array than simply changing the keys.
Seeing the code you used to assemble $plan would be helpful, but I'm going assume it was something like this
while ($line = $RES->fetch_assoc()) {
$plan[] = $line;
}
You can simply assign an explicit value while pulling the data from your database, like this:
while ($line = $RES->fetch_assoc()) {
$plan[$line['id']] = $line;
}
This is assuming $RES is the result set from your database query.
In my opinion, there is no simpler or more expressive technique than array_column() with a null second parameter. The null parameter informs the function to retain all elements in each subarray, the new 1st level keys are derived from the column nominated in the third parameter of array_column().
Code: (Demo)
$plan = array_column($plan, null, 'id');
Note: this technique is also commonly used to ensure that all subarrays contain a unique value within the parent array. This occurs because arrays may not contain duplicate keys on the same level. Consequently, if a duplicate value occurs while using array_column(), then previous subarrays will be overwritten by each subsequent occurrence of the same value to be used as the new key.
Demonstration of "data loss" due to new key collision.
$plans = array();
foreach($plan as $item)
{
$plans[$item['id']] = $item;
}
$plans contains the associative array.
This is just a simple solution.
$newplan = array();
foreach($plan as $value) {
$id = $value["id"];
unset($value["id"]);
$newplan[$id] = $value;
}

Categories