PHP - Search array for string - php

I have a page with a form where I post all my checkboxes into one array in my database.
The values in my database looks like this: "0,12,0,15,58,0,16".
Now I'm listing these numbers and everything works fine, but I don't want the zero values to be listed on my page, how am I able to search through the array and NOT list the zero values ?
I'm exploding the array and using a for each loop to display the values at the moment.

The proper thing to do is to insert a WHERE statement into your database query:
SELECT * FROM table WHERE value != 0
However, if you are limited to PHP just use the below code :)
foreach($values AS $key => $value) {
//Skip the value if it is 0
if($value == 0) {
continue;
}
//do something with the other values
}

In order to clean an array of elements, you can use the array_filter method.
In order to clean up of zeros, you should do the following:
function is_non_zero($value)
{
return $value != 0;
}
$filtered_data = array_filter($data, 'is_non_zero');
This way if you need to iterate multiple times the array, the zeros will already be deleted from them.

you can use array_filter for this. You can also specify a callback function in this function if you want to remove items on custom criteria.

Maybe try:
$out = array_filter(explode(',', $string), function ($v) { return ($v != 0); });

There are a LOT of ways to do this, as is obvious from the answers above.
While this is not the best method, the logic of this might be easier for phpnewbies to understand than some of the above methods. This method could also be used if you need to keep your original values for use in a later process.
$nums = '0,12,0,15,58,0,16';
$list = explode(',',$nums);
$newList = array();
foreach ($list as $key => $value) {
//
// if value does not equal zero
//
if ( $value != '0' ) {
//
// add to newList array
//
$newList[] = $value;
}
}
echo '<pre>';
print_r( $newList );
echo '</pre>';
However, my vote for the best answer goes to #Lumbendil above.

$String = '0,12,0,15,58,0,16';
$String = str_replace('0', '',$String); // Remove 0 values
$Array = explode(',', $String);
foreach ($Array AS $Values) {
echo $Values."<br>";
}
Explained:
You have your checkbox, lets say the values have been converted into a string. using str_replace we have removed all 0 values from your string. We have then created an array by using explode, and using the foreach loop. We are echoing out all the values of th array minux the 0 values.

Oneliner:
$string = '0,12,0,15,58,0,16';
echo preg_replace(array('/^0,|,0,|,0$/', '/^,|,$/'), array(',', ''), $string); // output 12,15,58,16

Related

Replace array value with more than one values

I have an array like this,
$array = array(
1,2,3,'4>12','13.1','13.2','14>30'
);
I want to find any value with an ">" and replace it with a range().
The result I want is,
array(
1,2,3,4,5,6,7,8,9,10,11,12, '13.1', '13.2', 14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30
);
My understanding:
if any element of $array has '>' in it,
$separate = explode(">", $that_element);
$range_array = range($separate[0], $separate[1]); //makes an array of 4 to 12.
Now somehow replace '4>12' of with $range_array and get a result like above example.
May be I can find which element has '>' in it using foreach() and rebuild $array again using array_push() and multi level foreach. Looking for a more elegant solution.
You can even do it in a one-liner like this:
$array = array(1,2,3,'4>12','13.1','13.2','14>30');
print_r(array_reduce(
$array,
function($a,$c){return array_merge($a,#range(...array_slice(explode(">","$c>$c"),0,2)));},
[]
));
I avoid any if clause by using range() on the array_slice() array I get from exploding "$c>$c" (this will always at least give me a two-element array).
You can find a little demo here: https://rextester.com/DXPTD44420
Edit:
OK, if the array can also contain non-numeric values the strategy needs to be modified: Now I will check for the existence of the separator sign > and will then either merge some cells created by a range() call or simply put the non-numeric element into an array and merge that with the original array:
$array = array(1,2,3,'4>12','13.1','64+2','14>30');
print_r(array_reduce(
$array,
function($a,$c){return array_merge($a,strpos($c,'>')>0?range(...explode(">",$c)):[$c]);},
[]
));
See the updated demo here: https://rextester.com/BWBYF59990
It's easy to create an empty array and fill it while loop a source
$array = array(
1,2,3,'4>12','13.1','13.2','14>30'
);
$res = [];
foreach($array as $x) {
$separate = explode(">", $x);
if(count($separate) !== 2) {
// No char '<' in the string or more than 1
$res[] = $x;
}
else {
$res = array_merge($res, range($separate[0], $separate[1]));
}
}
print_r($res);
range function will help you with this:
$array = array(
1,2,3,'4>12','13.1','13.2','14>30'
);
$newArray = [];
foreach ($array as $item) {
if (strpos($item, '>') !== false) {
$newArray = array_merge($newArray, range(...explode('>', $item)));
} else {
$newArray[] = $item;
}
}
print_r($newArray);

Need help to order strings by their internal value

I am using a text file as little database, and each line has this format:
3692|Giovanni|giojo982|0005405
9797|Stefano|stefy734|45367
2566|Marco|markkkk998|355647689
4721|Roberto|robn88|809678741
I need to order them alphabetically maintaining their indexes, if it's possible.
At the moment, I'm using this code, but in this situation logically it doesn't work any more.
Reading this post How can I sort arrays and data in PHP? I have not found nothing similar to my scenario.
So, I'm wondering... is there a solution?
$db_friends = "db_friends.txt";
$dblines = file($db_friends);
if(isset($_GET['A-Z'])) {
asort($dblines);
}
if(isset($_GET['Z-A'])) {
arsort($dblines);
}
foreach($dblines as $key => $profile) {
list($uni_id, $name_surname, $textnum_id, $num_id) = explode("|", $profile);
echo $name_surname;
}
A-Z
Z-A
How can I solve it?
I assume by alphabetically that you're trying to sort alphabetically by the name in the second column. The problem is, asort() and arsort() perform too simple a comparison to deal with the type of data you're giving them. They're just going to see the rows as strings, and sort by the number in the first column. One way to address this is by splitting the rows before sorting.
$db_friends = "db_friends.txt";
$dblines = file($db_friends);
// split each line into an array
$dblines = array_map(function($line){
return explode('|', $line);
}, $dblines);
Then you can sort by the second column more easily. Using uasort(), you'll maintain the index association.
if (isset($_GET['A-Z'])) {
uasort($dblines, function(array $a, array $b) {
return strcmp($a[1], $b[1]);
});
}
if (isset($_GET['Z-A'])) {
uasort($dblines, function(array $a, array $b) {
return strcmp($b[1], $a[1]);
});
}
Obviously if you make that change, you'll no longer need to explode when you iterate the sorted array, as it was already done in the first step.
foreach ($dblines as $key => $profile) {
list($uni_id, $name_surname, $textnum_id, $num_id) = $profile;
echo $name_surname;
}
You can avoid the complexity of a uasort() call if you just position your columns in the order that you want to alphabetize them. This method has the added benefit of sorting all column data from left to right. This means, regardless of sorting direction (asc or desc), my method will sort $rows[0], then $row[1], then $row[2], then $row[3].
I have also logically combined your two if statements and set ASC as the default sorting direction.
Code: (Demo)
$txt=['9999|Marco|markkkk998|355647689','1|Marco|markkkk998|355647689','3692|Giovanni|giojo982|0005405','9797|Stefano|stefy734|45367','2566|Marco|markkkk998|355647689','4721|Roberto|robn88|809678741'];
foreach($txt as $row){
$values=explode('|',$row);
$rows[]=[$values[1],$values[0],$values[2],$values[3]]; // just reposition Name column to be first column
}
if(isset($_GET['Z-A'])) {
arsort($rows); // this will sort each column from Left-Right using Z-A
}else{
asort($rows); // (default) this will sort each column from Left-Right using A-Z
}
// var_export($rows);
foreach($rows as $i=>$profile) {
echo "$i {$profile[0]}\n"; // name value
}
Output:
2 Giovanni
1 Marco
4 Marco
0 Marco
5 Roberto
3 Stefano
If I understood your question, you could try this function:
function sortValuesKeepKey($lines) {
//declare arrays to be used temporarily
$idNumbers = array();
$values = array();
$return = array();
//loop through each line and seperate the number at the beginning
//of the string from the values into 2 seperate arrays
foreach($lines as $line) {
$columns = explode("|", $line);
$id = array_shift($columns);
$idNumbers[] = $id;
$values[] = implode("|", $columns);
}
//sort the values without the numbers at the beginning
asort($values);
//loop through each value and readd the number originally at the beginning
//of the string
foreach($values as $key => $value) {
//use $key here to ensure your putting the right data back together.
$return[$key] = $idNumbers[$key]."|".$values[$key];
}
//return finished product
return $return;
}
Just pass it the lines as an array and it should return it ordered properly.
If you want to sort the values by name_surname, see the below code
$db_friends = "db_friends.txt";
$dblines = file($db_friends);
// loop the lines
foreach($dblines as $key => $profile) {
// explode each line with the delimiter
list($uni_id, $name_surname, $textnum_id, $num_id) = explode("|", $profile);
// create an array with name_surname as a key and the line as value
$array[$name_surname] = $profile;
}
// bases on the GET paramater sort the array.
if(isset($_GET['A-Z'])) {
ksort($array); //sort acceding
}
if(isset($_GET['Z-A'])) {
krsort($array); // sort descending
}
// loop the sorted array
foreach($array as $key => $value) {
echo $key; // display the name_surname.
}

Counting multidimensional array rows and their respective elements?

I'm doing something that is perhaps too long and strange to explain, but basically I've mapped a string in a complex way into an array in a way to make them jumbled up. This is an example of how it would look:
field[26][25]='x';
field[24][23]='z';
field[28][29]='y';
Now that I've successfully jumbled up the string in exactly the way I wanted, I need to reconstruct the linear result.
So I need to take row 1 of the array, and loop through all the elements in this row to combine them into a string. Then do the same thing with row 2 and so on to create one massive linear string.
How do I count how many rows and elements in those rows I have? For the life of me I cant even begin to find how to do this for multid arrays.
Kind regards
#u_mulder's got a solid answer there. For the number of elements, you'd just say:
$total = 0;
foreach( $matrix as $row ) $total += count($row);
For the concatenation of elements, you'd just say:
$concat = '';
foreach( $matrix as $row ) $concat .= implode('', $row);
Bob's your uncle. But really, is there a valid use case for such a strange mashup?
$field[26][25]='x';
$field[24][23]='z';
$field[28][29]='y';
$field_string = '';
array_walk_recursive ( $field , function($item, $key) use (&$field_string){
if(!is_array($item)){
$field_string .= $item;
}
});
echo $field_string;
Honestly, this is a little confusing. I may need more info but let me know if this helps
You can start with an empty string and use two nested foreach to iterate over lines and items on each line and append each item to the string:
$result = '';
foreach ($fields as $row) {
foreach ($row as $item) {
$result .= $item;
}
}
Or you can replace the entire inner foreach with $result .= implode('', $row);.
You can even replace the outer foreach with a call to array_map() then implode() the array produced by array_map() into a string:
$string = implode(
'',
array_map(
function (array $items) {
return implode('', $items);
},
$fields
)
);

Grabbing array from database, then getting information using each array value

totally stumped in this, basically I'm getting a comma seperated list from a user table, using it as an array and then using each value in the array to fetch data from a different table and output then.
$award_array = array($user_class->awards);
foreach($award_array as $award) {
$getaward = mysql_query("SELECT `name`, `text`, `image` FROM `awards_av` WHERE `id` = '".$award."'");
$awardstuff = mysql_fetch_array($getaward);
echo "<img src='".$awardstuff['image']."' alt='".$awardstuff['name']."' title='".$awardstuff['text']."' />";
}
This is only giving out the first number in the array ($user_class->awards in this case is 1,2,3,4,5,6)
Any help is much appreciated!
I think I see the problem. You cannot simply take a string of a comma separated list, and throw it inside an array() tag and expect it to automatically convert it to an array. You must use the explode() function to do that.
What you're trying to do:
<?php
$string = 'a,b,c,d,e';
$myarray = array($string);
foreach ($myarray as $k => $v) {
print $v .'<br />';
}
?>
Except that doesn't work. You need to convert the comma-separated list of values (which is a string) into an array, but you don't use array() to do that. You use PHP's built-in function called explode() -> http://php.net/explode like this...
<?php
$string = 'a,b,c,d,e';
$myarray = explode(',' $string);
foreach ($myarray as $k => $v) {
print $v .'<br />';
}
?>
I think that is the problem you're having

How to handle my data?

Edit: The aim of my method is to delete a value from a string in a database.
I cant seem to find the answer for this one anywhere. Can you concatenate inside a str_replace like this:
str_replace($pid . ",","",$boom);
$pid is a page id, eg 40
$boom is an exploded array
If i have a string: 40,56,12 i want to make it 56,12 however without the concatenator in it will produce:
,56,12
When I have the concat in the str_replace it doesnt do a thing. Is this possible?
Answering your question: yes you can. That code works as you would expect it to.
But this approach is wrong. It will not work for $pid = 12; (last element, without trailing coma) and will incorrectly replace 40, in $boom = '140,20,12';
You should keep it in array, search for unwanted value, if found unset it from the array and then implode with coma.
$boom = array_filter($boom);
$key = array_search($pid, $boom);
if($key !== false){
unset($boom[$key]);
}
$boom = implode(',',$boom);
[+] Your code does not work because $boom is an array, and str_replace operates on string.
As $boom is an array, you don't need to use array on your case.
Change this
$boom = explode(",",$ticket_array);
$boom = str_replace($pid . ",","",$boom);
$together = implode(",",$boom);
to
$together = str_replace($pid . ",","",$ticket_array);
Update: If you want still want to use array
$boom = explode(",",$ticket_array);
unset($boom[array_search($pid, $boom)]);
$together = implode(",",$boom);
After you have edited it becomes clear that you want to remove the value of $pid from the array $boom which contains one number as a value. You can use array_search to find if it is in at if in with which key. You can then unset the element from $boom:
$pid = '40';
$boom = explode(',', '40,56,12');
$r = array_search($pid, $boom, FALSE);
if ($r !== FALSE) {
unset($boom[$r]);
}
Old question:
Can you concatenate inside a str_replace like this: ... ?
Yes you can, see the example:
$pid = '40';
$boom = array('40,56,12');
print_r(str_replace($pid . ",", "", $boom));
Result:
Array
(
[0] => 56,12
)
Which is pretty much like you did so you might be looking for the problem at the wrong place. You can use any string expression for the parameter.
It might be easier for you if you're unsure to create a variable first:
$pid = '40';
$boom = array('40,56,12');
$search = sprintf("%d,", $pid);
print_r(str_replace($search, "", $boom));
You should store your "ticket array" in a separate table.
And use regular SQL queries (UPDATE, DELETE) to manipulate it.
A relational word in the name of your database is for the reason. And you are abusing this smart software with such a barbaric approach.
You could use str_split, it converts a string to an array, then with a foreach loop echo all the values except the first one.
$numbers_string="40,56,12";
$numbers_array = str_split($numbers_string);
//then, when you have the array of numbers, you could echo every number except the first separating them with a comma
foreach ($numbers_array as $key => $value) {
if ($key > 0) {
echo $value . ", ";
}
}
If you want is to skip a value not by it's position in the array, but for it's value then you could do this instead:
$unwanted_value="40";
foreach ($numbers_array as $key => $value) {
if ($value != $unwanted_value) {
echo $value . ", ";
}
else {
unset($numbers_array[$key]);
$numbers_array = array_values($numbers_array);
var_dump($numbers_array);
}
}

Categories