I have a array of val which has dynamic strings with underscores. Plus I have a variable $key which contains an integer. I need to match $key with each $val (values before underscore).
I did the following way:
<?php
$key = 2; //always a dynamic number
$val = array('3_33', '2_55'); //always a dynamic string with underscore
if(in_array($key, $val)) {
echo 'Yes';
}
else
{
echo 'No';
}
?>
Though this code works fine, I want to know if its a correct way or suggest some better alternative.
use this function for regex match from php.net
function in_array_match($regex, $array) {
if (!is_array($array))
trigger_error('Argument 2 must be array');
foreach ($array as $v) {
$match = preg_match($regex, $v);
if ($match === 1) {
return true;
}
}
return false;
}
and then change your code to use this function like this:
$key = 2; //always a dynamic number
$val = array('3_33', '2_55'); //always a dynamic string with underscore
if(in_array_match($key."_*", $val)) {
echo 'Yes';
}
else
{
echo 'No';
}
This should work :
foreach( $val as $v )
{
if( strpos( $v , $key .'_' ) === true )
{
echo 'yes';
}
else {
echo 'no';
}
}
you can use this
function arraySearch($find_me,$array){
$array2 =array();
foreach ($array as $value) {
$val = explode('_',$value);
$array2[] =$val[0];
}
$Key = array_search($find_me, $array2);
$Zero = in_array($find_me, $array2);
if($Key == NULL && !$Zero){
return false;
}
return $Key;
}
$key = 2; //always a dynamic number
$val = array('3_33', '2_55'); //always a dynamic string with underscore
$inarray = false;
foreach($val as $v){
$arr = explode("_", $val);
$inarray = $inarray || $arr[0] == $key
}
echo $inarray?"Yes":"No";
The given format is quite unpractically.
$array2 = array_reduce ($array, function (array $result, $item) {
list($key, $value) = explode('_', $item);
$result[$key] = $value;
return $result;
}, array());
Now you can the existence of your key just with isset($array2[$myKey]);. I assume you will find this format later in your execution useful too.
Related
$array = ['coke.','fanta.','chocolate.'];
foreach ($array as $key => $value) {
if (strlen($value)<6) {
$new[] = $value." ".$array[$key+1];
} else {
$new[] = $value;
}
}
This code doesn't have the desired effect, in fact it doesn't work at all. What I want to do is if an array element has string length less than 5, join it with the next element. So in this case the array should turn into this:
$array = ['coke. fanta.','chocolate.'];
$array = ['coke.','fanta.','chocolate.', 'candy'];
$new = [];
reset($array); // ensure internal pointer is at start
do{
$val = current($array); // capture current value
if(strlen($val)>=6):
$new[] = $val; // long string; add to $new
// short string. Concatenate with next value
// (note this moves array pointer forward)
else:
$nextVal = next($array) ? : '';
$new[] = trim($val . ' ' . $nextVal);
endif;
}while(next($array));
print_r($new); // what you want
Live demo
With array_reduce:
$array = ['coke.', 'fanta.', 'chocolate.', 'a.', 'b.', 'c.', 'd.'];
$result = array_reduce($array, function($c, $i) {
if ( strlen(end($c)) < 6 )
$c[key($c)] .= empty(current($c)) ? $i : " $i";
else
$c[] = $i;
return $c;
}, ['']);
print_r($result);
demo
<pre>
$array = ['coke.','fanta.','chocolate.'];
print_r($array);
echo "<pre>";
$next_merge = "";
foreach ($array as $key => $value) {
if($next_merge == $value){
continue;
}
if (strlen($value)<6) {
$new[] = $value." ".$array[$key+1];
$next_merge = $array[$key+1];
} else {
$new[] = $value;
}
}
print_r($new);
</pre>
Updated Code after adding pop after chocolate.
<pre>
$array = ['coke.','fanta.','chocolate.','pop'];
print_r($array);
echo "<br>";
$next_merge = "";
foreach ($array as $key => $value) {
if($next_merge == $value){
continue;
}
if (strlen($value)<6 && !empty($array[$key+1])) {
$new[] = $value." ".$array[$key+1];
$next_merge = $array[$key+1];
} else {
$new[] = $value;
}
}
print_r($new);
<pre>
You need to skip the iteration for the values that you have already added.
$array = ['coke.', 'fanta.', 'chocolate.'];
$cont = false;
foreach ($array as $key => $value) {
if ($cont) {
$cont = false;
continue;
}
if (strlen($value) < 6 && isset($array[$key+1])) {
$new[] = $value.' '.$array[$key+1];
$cont = true;
}
else {
$new[] = $value;
}
}
print_r($new);
hi i have an array of about 20/30 items big.
i need to have it loop threw the array and echo out only the items with the text p1 in them.
the array looks like so
"lolly","lollyp1","top","topp1","bum","bump1","gee","geep1"
and so on
i have tried to use something like this
foreach ($arr as $value) {
$needle = htmlspecialchars($_GET["usr"]);
$ret = array_keys(array_filter($arr, function($var) use ($needle){
return strpos($var, $needle) !== false;
}));
but all this gives me is a blank page or 1s
how can i have it echo out the items with p1 in them ?
Try This:
$needle = htmlspecialchars($_GET["usr"]);
$rtnArray = array();
foreach ($arr as $value) {
$rtnArray = strpos($value,$needle);
};
return $rtnArray;
If your trying to write directly to the page the lose the $rtnarray and echo:
$needle = htmlspecialchars($_GET["usr"]);
foreach ($arr as $value) {
echo strpos($value,$needle);
};
To only show ones with 'p1' then filter:
$needle = htmlspecialchars($_GET["usr"]);
foreach ($arr as $value) {
$temp = strpos($value,$needle);
if($temp > 1){
echo $value;
}
};
Using a direct loop with string-comparison would be a simple way to go here:
$needle = $_GET['usr'];
$matches = array();
foreach ($arr as $key => $value) {
if (strpos($value, $needle) !== false) {
$matches[] = $key;
}
}
The use of array_filter() in your post should work, pending the version of PHP you're using. Try updating to use a separate / defined function:
function find_needle($var) {
global $needle;
return strpos($var, $needle) !== false;
}
$ret = array_keys(array_filter($arr, 'find_needle'));
Codepad Example of the second sample
I have an array wich is structured like this
foo = stuff we don't care for this example
foo1_value
foo1_label
foo1_unit
foo2_value
foo3_label
foo3_value
Can you figure out a fast way to make it look like that ?
foo
foo1
value
label
unit
foo2
value
foo3
value
label
I'm actually trying with something like this :
array_walk($array, function($val, $key) use(&$nice_array) {
$match = false;
preg_match("/_label|_value|_unit|_libelle/", $key, $match);
if (count($match)) {
list($name, $subName) = explode('_', $key);
$nice_array[$name][$subName] = $val;
} else {
$nice_array[$key] = $val;
}
});
echo '<pre>';
print_r($nice_array);
echo '</pre>';
This is working I'll just have to reflect on the foo_foo_label thing and it's all good
You could use explode on the array keys, something like this:
$newArray = array();
foreach ( $array as $key => $value )
{
$parts = explode('_', $key);
$newArray[$parts[0]][$parts[1]] = $value;
}
Edit: update as detailed in comments. Will handle your foo_foo_value case as well as foo and foo_foo. There's really no reason to use array_walk if you're only passing the results off to a second array.
$newArray = array();
foreach ( $array as $key => $value ) {
if ( preg_match('/_(label|value|unit)$/', $key) === 0 ) {
$newArray[$key] = $value;
continue;
}
$pos = strrpos($key, '_');
$newArray[substr($key, 0, $pos)][substr($key, $pos+1, strlen($key))] = $value;
}
What you can do is loop over the array, and split (explode()) each key on _ to build your new array.
$newArray = array();
foreach($oldArray as $key=>$value){
list($name, $subName) = explode('_', $key);
if($subName !== NULL){
if(!isset($newArray[$name])){
$newArray[$name] = array();
}
$newArray[$name][$subName] = $value;
}
else{
$newArray[$name] = $value;
}
}
$nice_array = array();
array_walk($array, function($val, $key) use(&$nice_array) {
$match = false;
preg_match("/_label|_value|_unit|_libelle/", $key, $match);
if (count($match)) {
$tname = preg_split("/_label$|_value$|_unit$|_libelle$/",$key);
$name = $tname[0];
$subName = substr($match[0],1);
$nice_array[$name][$subName] = $val;
} else {
$nice_array[$key] = $val;
}
});
I'm trying to validate a string to an array of numbers. If the string only contains numbers then the function should validate, but in_array isn't working, any suggestions?
$list = array(0,1,2,3,4,5,6,7,8,9);
$word = 'word';
$split = str_split($word);
foreach ($split as $s) {
if (!in_array($s, $list)) {
print 'asdf';
}
}
here is the class:
class Validate_Rule_Whitelist {
public function validate($data, $whitelist) {
if (!Validate_Rule_Type_Character::getInstance()->validate($data)) {
return false;
}
$invalids = array();
$data_array = str_split($data);
foreach ($data_array as $k => $char) {
if (!in_array($char, $whitelist)) {
$invalids[] = 'Invalid character at position '.$k.'.';
}
}
if (!empty($invalids)) {
$message = implode(' ', $invalids);
return $message;
}
return true;
}
}
in_array comparison with loosely typed values is somewhat strange. What would work in your case is:
$list = array('0','1','2','3','4','5','6','7','8','9');
$word = 'word';
$split = str_split($word);
foreach ($split as $s) {
if (!in_array($s, $list, true)) {
print 'asdf';
}
}
This compares strings with strings and results in no surprises.
But, as noted in the comments already, this is quite wrong way to do things and it is much better to use filter_var() or regular expressions** to achieve what you're trying.
it's ugly as sin but it works, no elegant solution here, just a double loop, if you see any problems please let me know
$match = array();
foreach ($data_array as $k => $char) {
foreach ($whitelist as $w) {
if (!isset($match[$k])) {
if ($char === $w) {
$match[$k] = true;
}
}
}
if (!isset($match[$k]) || $match[$k] !== true) {
$invalids[$k] = 'Invalid character at position '.$k.'.';
}
}
Something along the lines of this should work:
<?php
$validate_me = '123xyz';
if(preg_match("/[^0-9]/", $validate_me, $matches))
print "non-digit detected";
?>
update: add the $type = gettype ... settype($char, $type) to allow === to function correctly when checking for integers
foreach ($data_array as $k => $char) {
foreach ($whitelist as $w) {
if (!isset($match[$k])) {
$type = gettype($w);
if (gettype($char) !== $type) {
settype($char, $type);
}
if ($char === $w) {
$match[$k] = true;
}
}
}
...
I have an array like the following:
5-9-21,
5-10-22,
5-10-22,
5-11-23,
3-17-29,
3-19-31,
3-19-31,
1-25-31,
7-30-31
I wil get a value dynamically. Then I have to compare that value with the middle part of array.
9,
10,
10,
11,
17,
19,
19,
25,
30
If it's matching then I have to remove the whole part from array.
For example. If I am getting a value dynamically is 19, then I wil match with that array. And 3-19-31 is there two times. So it will remove all 3-19-31. After exploding with "-".
How can I do this?
foreach($array as $key=>$value){
$parts = explode('-', $value);
if($parts[1] == $search) {
unset($array[$key]);
}
}
Or if your search is an array
foreach($array as $key=>$value){
$parts = explode('-', $value);
if(in_array($parts[1], $search)) {
unset($array[$key]);
}
}
You could use array_filter to get a new array.
$new_arr = array_filter($old_arr, function($var) use ($input) {
$ret = explode('-', $var);
return !(isset($ret[1]) && $ret[1] === $input);
});
Or use a normal loop and then use unset to remove the values.
for ($arr as $key => $value) {
$ret = explode('-', $value);
if (isset($ret[1]) && $ret[1] === $input) {
unset($arr[$key]);
}
}
use this function, this will give you all the keys which are matched:
function custom_array_search($keyword,$array){
if(!is_array($array)){
return false;
}
$ret_keys = array();
foreach($array as $key=>$value){
if(strpos("-{$keyword}-",$value)!==false){
$ret_keys[] = $key;
}
}
return $ret_keys;
}
This function will give you all keys in an array.
Now you can delete those i.e. unset all keys from that array. :)
<?php
$arr = array('5-9-21', '5-10-22', '5-10-22', '5-11-23', '3-17-29', '3-19-31', '3-19-31', '1-25-31', '7-30-31');
$k = '10';
#print_r($arr);
foreach ($arr as $key => $value)
{
$t = explode('-',$value);
if($t[1] == $k)
{
unset($arr[$key]);
#echo "deleted<br>";
}
}
#print_r($arr);
?>
You can try this...
$arr; // your array
$value = 19;
foreach ($arr as $key=>$a)
{
if(strpos($a, "-".$value."-") !== false)
unset($arr[$key]);
}
There are few ways you can do this. If you are going to have only one digit always in the first eliment of your triplet, the following code should work;
$triplet_array = array(5-9-21, 5-10-22, 5-10-22, 5-11-23, 3-17-29, 3-19-31, 3-19-31, 1-25-31, 7-30-31);
$i = 0;
foreach($triplet_array as triplet){
$middle = substring($triplet,2,0);
if($middle == $my_dynamic_value) unset($triplet_array[$i]);
$i++
}
but, if the first part is not going to contain only one digit always;
foreach($triplet_array as triplet){
$this_triplet = explode('-',$triplet);
if($this_triplet[1] == $my_dynamic_value) unset($triplet_array[$i]);
$i++
}
hope this helps :-)