array_search always gives me false - php

So i am trying to search an array and it always gives me false for some reason even tho the letter exists in the name array. This is what i want it to do , search the array, if a match exist it should add the name to the $data array and send it to the AJAX by encode it to JSON. But my IF always gives false
Edit: The answer in the other question did not solve this since that will always cause my array to return false
$user = array(
0 => array(
"id"=> 0,
"photo"=>"smily",
"name"=>"Name One",
),
1 => array(
"id"=> 0,
"photo"=>"smily",
"name"=>"Name Five",
),
2 => array(
"id"=> 0,
"photo"=>"smily",
"name"=>"Name Four",
),
3 => array(
"id"=> 0,
"photo"=>"smily",
"name"=>"Name Three",
),
);
$wordToSearch = "N";
$data = Array();
for($i = 0; $i < count($user); $i++)
{
if(array_search($wordToSearch, array_column($user, 'name')) == false)
{
array_push($data, array(
'name' => $user[$i]['name'],
'img' => $user[$i]['photo'],
'pos' => $user[$i]['position'],
'Id' => $user[$i]['id']
)
);
echo json_encode($data);
}
}

I could be wrong, but instead of
if(array_search($wordToSearch, array_column($user, 'name')) == false)
I think you want
if (strpos($user[$i]['name'], $wordToSearch) !== false)
array_column is used to get all the user names or all the user ids
array_search is used to search an array... but I think you're trying to search a string.
unrelated... instead of using array_push($data, array(...));, use $data[] = array(...); it's a bit more efficient as there's no function call.. and in my opinion, it's easier to code & read.

You can use strpbrk - strpbrk — Search a string for any of a set of characters
foreach ($user as $val) {
if (strpbrk($val['name'], $wordToSearch) != false) {
array_push($data, array(
'name' => $val['name'],
'img' => $val['photo'],
'pos' => $val['position'],
'Id' => $val['id']
)
);
echo json_encode($data);
}
}
}

Related

How to use a while loop result within three dimensional array in php?

I would like to pass a while loop result as a value to three dimensional array,i have tried but i couldn't get it.I am trying to solve this from few days.Any suggestions or answers are appreciated.Thank you
$messages = array(
'sender' => "akhil",
'messages' => array(
//////////////while loop starts
while($i < $data){
array(
'number' =>$data[$i],//////here i want to pass the while loop
variable
'text' => rawurlencode('Hello,.........')
)
$i++;
}
/////////////while loop ends
)
);
///the would like to get the below result
$messages = array(
'sender' => "akhil",
'messages' => array(
array(
'number' => 918xxxxxx,
'text' => rawurlencode('Hello,------')
),
array(
'number' => 9196xxxxxx,
'text' => rawurlencode('Hello,----')
)
), array(
'number' => 919xxxxx,
'text' => rawurlencode('Hello,----')
)
)
);
You just need to create the array outside the while loop and then push values into it inside the loop. Your code is almost there...
$messages = array('sender' => "akhil",
'messages' => array()
);
while ($i < count($data)) {
$messages['messages'][] = array('number' => $data[$i],
'text' => rawurlencode('Hello,.........'));
$i++;
}
Demo on 3v4l.org
What you are looking for is called an Anonymous function.
You can achieve your expected behavior by doing this:
'messages' => (function(){
$res = [];
while($i < $data){
$res[] = [
'number' =>$data[$i],//////here i want to pass the while loop variable
'text' => rawurlencode('Hello,.........')
];
$i++;
}
return $res;
})(),
...
I do not know the exact structure of your data, but I would swap the while for an array_map(). It would look like this:
'messages' => array_map(function($d){
return [
'number' =>$d,
'text' => rawurlencode('Hello,.........')
]
},$data),
...
Hohpe that helps,

Filter an indexed array with one regex filter using filter_var_value

I have a csv file that has lines of data, each row can have variable number of values.
I want to filter each line of the file to see if it has special characters or wrong values, if yes, the line will be skipped from the whole process.
So here is my code:
<?php
if (($handle = fopen('file.csv', "r")) !== false) {
while (($line = fgetcsv($handle, 1024, ";")) !== false) {
$keys = array('key');
foreach($line as $value){
$arr[] = array_fill_keys($keys,$value);
}
$args = array('filter' => FILTER_VALIDATE_REGEXP,
'options' => array('regexp' => '/[a-zA-Z0-9_:.()\s-\/]*/'), );
$result = filter_var_array($arr,$args);
var_dump($result);
}
}
fclose($handle);
?>
My problem here, is that the line as an array of values, is an indexed array, without keys, and I tried to fill in the keys but I still don't get good results and the values don't get filtered.
My second problem, is that I want to apply one filter on all the values, this filter is a regexp, so I cant just do this :
filter_var_array($arr,FILTER_VALIDATE_REGEXP);
Because I'll have to provide the options:
PHP Warning: filter_var_array(): 'regexp' option missing
Something like this doesn't work eather :
filter_var_array($line,FILTER_VALIDATE_REGEXP,[ 'options' => array('regexp' => '/[a-zA-Z0-9_:.()\s-\/]*/')]);
because the parameters of filter_var_array should be 2 arrays and a boolean:
PHP Warning: filter_var_array() expects parameter 3 to be boolean
So to sum up:
How to filter this file using one filter in the filter_var_array?
If it's impossible, is there a better way to analyse the whole file
and see if the content matches the regexp ?
If a line (array) has 4 elements in it (one,two,three,four), then your loop:
$keys = array('key');
foreach($line as $value){
$arr[] = array_fill_keys($keys,$value);
}
will create:
$arr=array(
0=>array("key"=>"one"),
1=>array("key"=>"two"),
2=>array("key"=>"three"),
3=>array("key"=>"four"),
)
That seems unnecessarily multidimensional.
Also, your regex is doomed to be true, it is asking for 0 or more of the acceptable characters anywhere in the string.
I'll make a regex pattern assumption and adjust it for you.
Try this:
foreach($line as $key=>$value){
$arr["k$key"]=$value;
$filters["k$key"]=array(
'filter'=>FILTER_VALIDATE_REGEXP,
'options'=>array('regexp'=>'/^[a-zA-Z0-9_:.()\s-\/]*$/')
// the regex will allow an empty string
// or a string of any length containing only those characters.
);
}
$result=filter_var_array($arr,$filters);
if(in_array(false,$result)){
echo "Line not valid";
}else{
var_export($result); // with no invalid values, $result == $arr
}
Here is a Demo.
Variable outputs:
$arr=array(
'k0' => 'one',
'k1' => 'two',
'k2' => 'three',
'k3' => 'four',
)
$filter=array(
'k0' => array(
'filter' => 272,
'options' => array('regexp' => '/^[a-zA-Z]*$/'),
),
'k1' => array(
'filter' => 272,
'options' => array('regexp' => '/^[a-zA-Z]*$/'),
),
'k2' => array(
'filter' => 272,
'options' => array('regexp' => '/^[a-zA-Z]*$/'),
),
'k3' => array(
'filter' => 272,
'options' => array('regexp' => '/^[a-zA-Z]*$/'),
)
)

sorting a multi dimensional array in php

I have an array of arrays, as such
$statuses = array(
[0] => array('id'=>10, 'status' => 'active'),
[1] => array('id'=>11, 'status' => 'closed'),
[2] => array('id'=>12, 'status' => 'active'),
[3] => array('id'=>13, 'status' => 'stopped'),
)
I want to be able to make a new array of arrays and each of those sub arrays would contain the elements based on if they had the same status.
The trick here is, I do not want to do a case check based on hard coded status names as they can be random. I want to basically do a dynamic comparison, and say "if you are unique, then create a new array and stick yourself in there, if an array already exists with the same status than stick me in there instead". A sample result could look something like this.
Ive really had a challenge with this because the only way I can think to do it is check every single element against every other single element, and if unique than create a new array. This gets out of control fast if the original array is larger than 100. There must be some built in functions that can make this efficient.
<?php
$sortedArray = array(
['active'] => array(
array(
'id' => 10,
'status' => 'active'
),
array(
'id' => 12,
'status' => 'active'
)
),
['closed'] => array(
array(
'id' => 11,
'status' => 'active'
)
),
['stopped'] => array(
array(
'id' => 13,
'status' => 'active'
)
),
)
$SortedArray = array();
$SortedArray['active'] = array();
$SortedArray['closed'] = array();
$SortedArray['stopped'] = array();
foreach($statuses as $Curr) {
if ($Curr['status'] == 'active') { $SortedArray['active'][] = $Curr; }
if ($Curr['status'] == 'closed') { $SortedArray['closed'][] = $Curr; }
if ($Curr['status'] == 'stopped') { $SortedArray['stopped'][] = $Curr; }
}
You can also do it with functional way though it's pretty the same like Marc said.
$sorted = array_reduce($statuses, function($carry, $status) {
$carry[$status['status']][] = $status;
return $carry;
}, []);

Check if an array of an array contains a certain string

I'm checking to make sure an array of arrays does not contain certain strings before adding any new child arrays to the parent array
I want to make sure that if an array with the same website and condition exists a new child array will not be added to the parent array.
e.g. in this example the $newArr must not be inserted in to the array $arr because their already exists an array with the same website and condition.
$arr = array(
array(
'website' => 'amazon',
'price' => 20,
'location' => 'uk',
'link' => '...',
'condition' => 'new'
),
array(
'website' => 'abe',
'price' => 20,
'location' => 'uk',
'link' => '...',
'condition' => 'new'
)
);
$newArr = array(
'website' => 'amazon',
'price' => 60,
'location' => 'uk',
'link' => '...',
'condition' => 'new'
)
I'm looking for an easy solution as using the function in_array on the parent array is not enough.
code so far
$arr = array();
foreach($table->find('tr.result') as $row){
if(($website = $row->find('a img',0))
&& ($price = $row->find('span.results-price a',0))
&& ($location = $row->find('.results-explanatory-text-Logo'))
&& ($link = $row->find('a',0))){
$website = str_replace( array('.gif','.jpg','.png'), '', basename($website->src));
$price = floatval(trim(str_replace(',', '', $price->innertext), "£"));
$location = "uk";
$link = $link->href;
$arr[] = array(
'website' => $website,
'price' => $price,
'location' => $location,
'link' => $link,
'condition' => 'new'
);
}
}
You loop over $arr each time to look for $website and $condition (always 'new'?) or you can keep a secondary array of the found keys. If you're starting with an empty $arr each time, the second approach will work and be faster.
$arr = array();
$keys = array();
foreach($table->find('tr.result') as $row){
if(...){
...
$condition = 'new'; // set as needed
// track seen keys
$key = $website . '|' . $condition; // assumes neither field contains '|'
if (!isset($keys[$key])) {
$keys[$key] = true;
$arr[] = array(...);
}
}
}
I hope the comments in the below code speak for themselves... I'm not a PHP pro, and this is probably not the most elegant way, but I believe the logic makes sense. Obviously the $new_array object has some variables that aren't declared but it's for example only.
I hope that helps and that no one down votes me :)
<?php
// Original array
$arr = array();
foreach($result as $row) {
// Get the new array as an object first so we can check whether to add to the loop
$new_array = array(
'website' => $website,
'price' => $price,
'location' => $location,
'link' => $link,
'condition' => 'new'
);
// If the original array is empty there's no point in looping through it
if(!empty($arr)) {
foreach($arr as $child) {
// Check through each item of the original array
foreach($new_array as $compare) {
// Compare each item in the new array against the original array
if(in_array($compare, $child)) {
// if there's a match, the new array will not get added
continue;
}
}
}
}
// If there's no match, the new array gets added
$arr[] = $new_array;
}
?>

Array - custom foreach function

I have an array in this form:
$data = array(
array(
'id' => '1',
'bar' => 'foo',
'page' => 'front',
),
array(
'id' => 'bar',
'bar' => 'foo',
'page' => 'front',
),
array(
'id' => 'different,
'bar' => 'bar',
'page' => 'back',
),
array(
'id' => 'another',
'title' => __("Custom CSS",'solidstyle_admin'),
'foo' => 'bar',
'page' => 'back',
),
);
And I want to list all ids grouped by pages and saved as variables, so if the above array is an input then output will look just like this one:
$front = array('1','bar');
$back = array('different','another');
//$data['page'] = array($id1, $id2, (...));
I was trying to do that using foreach and this is how it starts:
function my_output() {
foreach($data as $something) {
$id = $something['id'];
$page = $something['page'];
}
return $output;
}
I was trying multiple foreach loops, and the best result I got was:
front = 1
front = bar
back = different
back = another
But I have absolutely no idea how to achieve what I want to do, I don't want anyone to do my job, just any hints? Keep in mind I'm a bit new to PHP and I don't know too much about arrays.
Thank you!
Sounds like you want:
$ids = array();
foreach ($data as $page) {
$pageName = $page['page'];
// create an empty array for your IDs
if (!isset($ids[$pageName])) {
$ids[$pageName] = array();
}
// add to the array of IDs
$ids[$pageName][] = $page['id'];
}
var_dump($ids); // array('front' => array('1', 'bar'), ...
Stick with the loop idea and do a conditional check.
function my_output() {
$front = array();
$back = array();
foreach($data as $something) {
$id = $something['id'];
$page = $something['page'];
if ($page === 'front') {
$front[] = $id;
} else if ($page === 'back') {
$back[] = $id;
}
}
// Not sure what you want to return here, but you could return an array of pages
$output = array('front' => $front, 'back' => $back);
return $output;
}
This will return something similar to:
$output = array(
'front' => array(
0 => '1',
1 => 'bar',
),
'back' => array(
0 => 'something',
1 => 'another',
)
)
Edit: Keep in mind that my answer only accounts for the two pages you listed in your answer. If you have more pages you can also use what cbuckley's answer showed.

Categories