Consider an array like this,
$sports = array('Football','cricket ball','tennis ball','shuttle bat','hockey stick');
I want to create an array from $sports like this,
$ball = array('Football','cricket ball','tennis ball');
based on the search key(here it is 'ball').
If am looping through the array $sports and checking one by one, will get the result. But then am already inside a loop and that may be even loops more than 50,000 times. So thought of avoiding another loop.
Is there any other way to get this done?
Thanks
Try array_filter() + preg_match() functions:
<?php
header('Content-Type: text/plain; charset=utf-8');
$array = array('Football','cricket ball','tennis ball','shuttle bat','hockey stick');
$word = 'ball';
$results = array_filter(
$array,
function($value) use ($word){
return preg_match('/' . $word . '/i', $value);
}
);
print_r($results);
?>
Shows:
Array
(
[0] => Football
[1] => cricket ball
[2] => tennis ball
)
$sports = array('Football','cricket ball','tennis ball','shuttle bat','hockey stick');
$input = 'ball';
$result = array_filter($sports, function ($item) use ($input) {
if (stripos($item, $input) !== false) {
return $item;
}
});
print_r($result);
Related
I have strings in following format:
$strings[1] = cat:others;id:4,9,13
$strings[2] = id:4,9,13;cat:electric-products
$strings[3] = id:4,9,13;cat:foods;
$strings[4] = cat:drinks,foods;
where cat means category and id is identity number of a product.
I want to split these strings and convert into arrays $cats = array('others'); and $ids = array('4','9','13');
I know that it can be done by foreach and explode function through multiple steps. I think I am somewhere near, but the following code does not work.
Also, I wonder if it can be done by preg_match or preg_split in fewer steps. Or any other simpler method.
foreach ($strings as $key=>$string) {
$temps = explode(';', $string);
foreach($temps as $temp) {
$tempnest = explode(':', $temp);
$array[$tempnest[0]] .= explode(',', $tempnest[1]);
}
}
My desired result should be:
$cats = ['others', 'electric-products', 'foods', 'drinks';
and
$ids = ['4','9','13'];
One option could be doing a string compare for the first item after explode for cat and id to set the values to the right array.
$strings = ["cat:others;id:4,9,13", "id:4,9,13;cat:electric-products", "id:4,9,13;cat:foods", "cat:drinks,foods"];
foreach ($strings as $key=>$string) {
$temps = explode(';', $string);
$cats = [];
$ids = [];
foreach ($temps as $temp) {
$tempnest = explode(':', $temp);
if ($tempnest[0] === "cat") {
$cats = explode(',', $tempnest[1]);
}
if ($tempnest[0] === "id") {
$ids = explode(',', $tempnest[1]);
}
}
print_r($cats);
print_r($ids);
}
Php demo
Output for the first item would for example look like
Array
(
[0] => others
)
Array
(
[0] => 4
[1] => 9
[2] => 13
)
If you want to aggregate all the values in 2 arrays, you can array_merge the results, and at the end get the unique values using array_unique.
$strings = ["cat:others;id:4,9,13", "id:4,9,13;cat:electric-products", "id:4,9,13;cat:foods", "cat:drinks,foods"];
$cats = [];
$ids = [];
foreach ($strings as $key=>$string) {
$temps = explode(';', $string);
foreach ($temps as $temp) {
$tempnest = explode(':', $temp);
if ($tempnest[0] === "cat") {
$cats = array_merge(explode(',', $tempnest[1]), $cats);
}
if ($tempnest[0] === "id") {
$ids = array_merge(explode(',', $tempnest[1]), $ids);
}
}
}
print_r(array_unique($cats));
print_r(array_unique($ids));
Output
Array
(
[0] => drinks
[1] => foods
[3] => electric-products
[4] => others
)
Array
(
[0] => 4
[1] => 9
[2] => 13
)
Php demo
I don't generally recommend using variable variables, but you are looking for a sleek snippet which uses regex to avoid multiple explode() calls.
Here is a script that will use no explode() calls and no nested foreach() loops.
You can see how the \G ("continue" metacharacter) allows continuous matches relative the "bucket" label (id or cat) by calling var_export($matches);.
If this were my own code, I'd probably not create separate variables, but a single array containing id and cat --- this would alleviate the need for variable variables.
By using the encountered value as the key for the element to be added to the bucket, you are assured to have no duplicate values in any bucket -- just call array_values() if you want to re-index the bucket elements.
Code: (Demo) (Regex101)
$count = preg_match_all(
'/(?:^|;)(id|cat):|\G(?!^),?([^,;]+)/',
implode(';', $strings),
$matches,
PREG_UNMATCHED_AS_NULL
);
$cat = [];
$id = [];
for ($i = 0; $i < $count; ++$i) {
if ($matches[1][$i] !== null) {
$arrayName = $matches[1][$i];
} else {
${$arrayName}[$matches[2][$i]] = $matches[2][$i];
}
}
var_export(array_values($id));
echo "\n---\n";
var_export(array_values($cat));
All that said, I probably wouldn't rely on regex because it isn't very readable to the novice regex developer. The required logic is much simpler and easier to maintain with nested loops and explosions. Here is my adjustment of your code.
Code: (Demo)
$result = ['id' => [], 'cat' => []];
foreach ($strings as $string) {
foreach (explode(';', $string) as $segment) {
[$key, $values] = explode(':', $segment, 2);
array_push($result[$key], ...explode(',', $values));
}
}
var_export(array_unique($result['id']));
echo "\n---\n";
var_export(array_unique($result['cat']));
P.s. your posted coding attempt was using a combined operator .= (assignment & concatenation) instead of the more appropriate combined operator += (assignment & array union).
I'm looking for an alternative function that works the same as in_array but which could also check if the search term only contains a part of the given element instead of the whole element:
Currently working with the following script:
$attributes = array('dogs', 'cats', 'fish');
if (in_array($attributes, array('dog','cats','fishess'), true )) {
* does something for cats, but not for dogs and fish
because the function only checks if the given term is identical to the word in the array instead of only a part of the word *
}
How would I build my up function so that it passes words which only contain parts of word in the array aswell?
Preferred example would look something like this:
$words = array('fish', 'sharks');
if (*word or sentence part is* in_array($words, array('fishing', 'sharkskin')){
return 'your result matched 2 elements in the array $words
}
The solution using array_filter and preg_grep functions:
$words = ['fish', 'sharks', 'cats', 'dogs'];
$others = ['fishing', 'sharkskin'];
$matched_words = array_filter($words, function($w) use($others){
return preg_grep("/" . $w . "/", $others);
});
print_r($matched_words);
The output:
Array
(
[0] => fish
[1] => sharks
)
Try the code below:
<?php
$what = ['fish', 'sharks'];
$where = ['fishing', 'sharkskin'];
foreach($what as $one)
foreach($where as $other)
echo (strpos($other, $one)!==false ? "YEP! ".$one." is in ".$other."<br>" : $one." isn't in ".$other."<br>");
?>
Hope it helps =}
Why not just make your own piece of code / function?
foreach ($item in $attributes) {
foreach ($item2 in array('dog','cats','fishess')) {
// Check your custom functionality.
// Do something if needed.
}
}
You can take a look at array_intersect, but it is not going to check pattern matches (which you have somehow mentioned?)
array_intersect() returns an array containing all the values of array1 that are present in all the arguments. Note that keys are preserved.
foreach (array_intersects($attributes, array('dog','cats','fishess') {
// do something.
}
you can use:
array_filter($arr, function($v, $k) {
// do whatever condition you want
return in_array($v, $somearray);
}, ARRAY_FILTER_USE_BOTH);
this function call on every item in the array $arr a function that you can customize, in your case check whether you element in another array or not
I would go with:
$patterns = array('/.*fish.*/', '/.*sharks.*/');
$subjects = array('fishing', 'aaaaa', 'sharkskin');
$matches = array();
preg_replace_callback(
$patterns,
function ($m) {
global $matches;
$matches[] = $m[0];
return $m[0];
},
$subjects
);
print_r($matches); // Array ( [0] => fishing [1] => sharkskin )
I'm looking to get an array of ID's from the following string.
[vc_gallery type="flexslider_fade" interval="3" images="3057,2141,234" onclick="link_image" custom_links_target="_self" img_size="large"]
Ideally, i'd like to look at this string and get an array of the INT values within images. e.g.
array("3057", "2141", "234");
find images value and explode it to receive array
$str = '[vc_gallery type="flexslider_fade" interval="3" images="3057,2141,234" onclick="link_image" custom_links_target="_self" img_size="large"]';
if (preg_match('/images\s*=\s*\"([^\"]+)\"/', $str, $m)) {
$res = explode(',', $m[1]);
print_r($res);
}
Another solution using explode and strpos functions:
$str = '[vc_gallery type="flexslider_fade" interval="3" images="3057,2141,234" onclick="link_image" custom_links_target="_self" img_size="large"]';
foreach (explode(" ", $str) as $v) {
if (strpos($v, "images=") === 0) {
$result = explode(",", explode('"', $v)[1]);
break; // avoids redundant iterations
}
}
print_r($result);
The output:
Array
(
[0] => 3057
[1] => 2141
[2] => 234
)
WP outputs an array:
$therapie = get_post_meta($post->ID, 'Therapieen', false);
print_r($therapie);
//the output of print_r
Array ( [0] => Massagetherapie )
Array ( [0] => Hot stone )
Array ( [0] => Massagetherapie )
How would I merge these arrays to one and delete all the exact double names?
Resulting in something like this:
theArray
(
[0] => Massagetherapie
[1] => Hot stone
)
[SOLVED] the problem was if you do this in a while loop it wont work here my solution, ty for all reply's and good code.: Its run the loop and pushes every outcome in a array.
<?php query_posts('post_type=therapeut');
$therapeAr = array(); ?>
<?php while (have_posts()) : the_post(); ?>
<?php $therapie = get_post_meta($post->ID, 'Therapieen', true);
if (strpos($therapie,',') !== false) { //check for , if so make array
$arr = explode(',', $therapie);
array_push($therapeAr, $arr);
} else {
array_push($therapeAr, $therapie);
} ?>
<?php endwhile; ?>
<?php
function array_values_recursive($ary) { //2 to 1 dim array
$lst = array();
foreach( array_keys($ary) as $k ) {
$v = $ary[$k];
if (is_scalar($v)) {
$lst[] = $v;
} elseif (is_array($v)) {
$lst = array_merge($lst,array_values_recursive($v));
}}
return $lst;
}
function trim_value(&$value) //trims whitespace begin&end array
{
$value = trim($value);
}
$therapeAr = array_values_recursive($therapeAr);
array_walk($therapeAr, 'trim_value');
$therapeAr = array_unique($therapeAr);
foreach($therapeAr as $thera) {
echo '<li><input type="checkbox" value="'.$thera.'">'.$thera.'</input></li>';
} ?>
The following should do the trick.
$flattened = array_unique(call_user_func_array('array_merge', $therapie));
or the more efficient alternative (thanks to erisco's comment):
$flattened = array_keys(array_flip(
call_user_func_array('array_merge', $therapie)
));
If $therapie's keys are strings you can drop array_unique.
Alternatively, if you want to avoid call_user_func_array, you can look into the various different ways of flattening a multi-dimensional array. Here are a few (one, two) good questions already on SO detailing several different methods on doing so.
I should also note that this will only work if $therapie is only ever a 2 dimensional array unless you don't want to flatten it completely. If $therapie is more than 2 dimensions and you want to flatten it into 1 dimension, take a look at the questions I linked above.
Relevant doc entries:
array_flip
array_keys
array_merge
array_unique
call_user_func_array
It sounds like the keys of the arrays you are generating are insignificant. If that's the case, you can do a simple merge then determine the unique ones with built in PHP functions:
$array = array_merge($array1, $array2, $array3);
$unique = array_unique($array);
edit: an example:
// Emulate the result of your get_post_meta() call.
$therapie = array(
array('Massagetherapie'),
array('Hot stone'),
array('Massagetherapie'),
);
$array = array();
foreach($therapie as $thera) {
$array = array_merge($array, $thera);
}
$unique = array_unique($array);
print_r($unique);
PHP's array_unique() will remove duplicate values from an array.
$tester = array();
foreach($therapie as $thera) {
array_push($tester, $thera);
}
$result = array_unique($tester);
print_r($result);
$data1 = "mathews,luks,john,ethan,neil";
$data2 = "80%,60%,78%,55%,62%";
want to combine both like
mathews = 80%
Luks = 60%
John = 78%
etc.... how to do this?? I want print result exactly like Mathews = 80%
http://us.php.net/manual/en/function.array-combine.php
$result = array_combine ( explode ( ',', $data1 ), explode ( ',', $data2 );
to extract:
if you know key name: echo $result ['john'];
if all: foreach ( $result as $key => $value ) { echo $key . ' : ' . $value; }
to gey list of keys: $list = explode ( ',', $data1 ) or $list = array_keys ( $result );
http://us.php.net/manual/en/function.array-keys.php
How about this...?
print_r(array_combine(explode(',',$data1),explode(',',$data2)));
$arr = array_combine(explode(',', $data1), explode(',', $data2));
Or
$names = explode(',', $data1);
$par = explode(',', $data2);
$arr = array();
foreach ($names as $idx=>$name)
{
$arr[$name] = $par[$idx];
}
Use the built in array_combine
You may consider using preg_split to the string:
$names = preg_split("/[,]+/", "mathews,luks,john,ethan,neil");
$percent = preg_split("/[,]+/", "80%,60%,78%,55%,62%");
Then you can use array_combine like many others suggest, or simply use 2 arrays $names and $percent along with the shared index, for example, $names[2] goes along with $percent[2].
As stated by bensui:
$data1 = "mathews,luks,john,ethan,neil";
$data2 = "80%,60%,78%,55%,62%";
$array = array_combine(explode(',',$data1), explode(',',$data2));
This will result in:
print_r($array);
Array
(
[mathews] => 80%
[luks] => 60%
[john] => 78%
[ethan] => 55%
[neil] => 62%
)
This will give you the ability easily update the assocaited scores simple by doing:
$array['mathews'] = '90%';
You can then use the array_slice I offered you earlier to discard john and ethan:
$newArray = array_slice($array, 2, 2);
This will give you:
print_r($newArray);
Array
(
[mathews] => 80%
[luks] => 60%
[neil] => 62%
)
Note: there is nothing wrong with using loops, the fact of the matter is they are often over used when there are methods built in to the language to solve many common problems.
If you are some kind of anti-loop fanatic, you could create a recursive function.
function no_loop_combine($data1,$data2,$index)
{
if($index == count($data1))
{
return '';
}
else
{
return $data1[$index] . ' = ' . $data2[index]
. '\n' . no_loop_combine($data1,$data2,$index + 1);
}
}
Then you just have to call your function specifying $index = 0, and you will get the result. Using array_combine probably is still using a loop, just masked by the fact that you are calling a function. Using recursion means there is no loop. Just realized that your initial input is a string, and not a loop. So you could call explode before passing it into the function as so:
no_loop_combine(explode(',', $data1 ),explode(',',$data2),0);