Sort the contents of the textfile in ascending - php

I am trying to develop a code that will sort the contents of the text file in ascending order. I have read the contents of the file and was able to display the texts.
I am having difficulty sorting them out in from low to high order, word by word.
I have tried the asort from php.net, but just could not get the code to work well.
thanks.

To answer your second question, you can read the text file into into a variable (like you've said you have already), eg. $variable, then use explode (http://php.net/manual/en/function.explode.php) to separate, at each space, each word into an array:
//$variable is the content from your text file
$output = explode(" ",$variable); //explode the content at each space
//loop through the resulting array and output
for ($counter=0; $counter < count($output); $counter++) {
echo $output[$counter] . "<br/>"; //output screen with a line break after each
} //end for loop
If your paragraph contains commas etc which you don't want to output you can replace those in the variable before exploding it.

//Split file by newlines "\n" into an array using explode()
$file = explode("\n",file_get_contents('foo.txt'));
//sort array with sort()
sort($file);
//Build string and display sorted contents.
echo implode("\n<br />",$file);
Sort functions needs to have an array as argument, make sure your file is in an array. asort is for associative arrays, so unless you need to keep the array keys you can use sort instead.

$file = "Hello world\ngoodbye.";
$words = preg_split("/\s+/", $file);
$clean_words = preg_replace("/[[:punct:]]+/", "", $words);
foreach ($clean_words as $key => $val) {
echo "words[" . $key . "] = " . $val . "\n";
}
--output:--
words[0] = Hello
words[1] = world
words[2] = goodbye
sort($clean_words, SORT_STRING | SORT_FLAG_CASE);
foreach ($clean_words as $key => $val) {
echo "words[" . $key . "] = " . $val . "\n";
}
--output:--
words[0] = goodbye
words[1] = Hello
words[2] = world

Try this
<?php
$filecontent = file_get_contents('exemple.txt');
$words = preg_split('/[\s,.;":!()?\'\-\[\]]+/', $filecontent, -1, PREG_SPLIT_NO_EMPTY);
$array_lowercase = array_map('strtolower', $words);
array_multisort($array_lowercase, SORT_ASC, SORT_STRING, $words);
foreach($words as $value)
{
echo "$value <br>";
}
?>

Related

Add +1 to each index found in an array

I have a form that takes in a users input and puts it in an array, the user then chooses a word they want to find in said array. Thereafter the array is checked to see what each index of the word is as well as each occurrence of the word in the text.
So if you write the string "What is what" and want to find the word "what" it will say that the position of the word is "0 and 2" whereas I'd like it to say "1 and 3". How do I go about this?
Here's the code:
<form action="sida3.php" method="post">
Text: <textarea name="textarea"></textarea>
<br> Search word: <input type="text" name="search">
<br>
<input type="submit" name="submit" value="Submit">
</form>
<?php
if(isset($_POST['submit'])){
$parts = explode(" ", $_POST['textarea']);
$strName = $_POST['search'];
print_r ($parts);
echo '<br>';
foreach($parts as $item) {
if ($item == $strName) {
$counter++;
}
}
echo "The word $strName can be found at: ";
echo implode(' ', array_keys($parts, $strName));
echo "<br>";
echo "The word $strName was found $counter times";
}
I'm not sure what you're doing with the foreach or if that's where you want to create the positions, but:
foreach($parts as $pos => $item) {
if ($item == $strName) {
$result[] = $pos + 1;
}
}
Then just:
echo implode(' ', $result);
You can map +1 over the array keys before imploding. I also suggested another way to find the search term and count the occurrences, if you're interested in that, but map will work with the way you're currently doing it as well.
$found = array_intersect($parts, [$strName]);
echo "The word $strName can be found at: ";
echo implode(' ', array_map(function($x) { return $x + 1; }, array_keys($found)));
echo "<br>";
echo "The word $strName was found ". count($found) ." times";
You can use array_combine to combine a range from 1 to count of the array with the values.
$str = "This is a string.";
$arr = explode(" ", $str);
$range = range(1,count($arr)); // creates a range from 1 -> count of $arr
$new = array_combine($range, $arr); // sets the range as the key and $arr as the value
var_dump($new);
https://3v4l.org/SUhVM
Now that I look at the question again I see that there is a big flaw we all have missed.
If the word you search for is next to a dot, comma or other symbol it won't be counted.
Here I use the code I had in the answer above but added preg_replace to remove all characters that is not a-Z 0-9 (meaning english alphabet, change to suit your needs).
I then use substr_count to find the number of words without looping.
I use array_intersect to reduce the array to only the items matching $find, and grab the keys with array_keys. The key is the positions of the words.
All done without looping.
$str = "This is a car. Automobile (car) is another word for it. You can also add a hashtag, #car";
$find = "car";
$count = substr_count($str, $find);
$str = preg_replace("/[^a-zA-Z 0-9]/", "", $str);
$arr = explode(" ", $str);
$range = range(1,count($arr));
$new = array_combine($range, $arr);
$positions = array_keys(array_intersect($new, [$find]));
echo $find . " was found " . $count . " times. At positions: " . implode(", ", $positions);
Just looping and matching with == will only find one car in this string.
https://3v4l.org/sHAd5

Explode and assign it to a multi-dimensional array

I found this code in another post which I found quite helpful but for me it's only half the equation. In line with the following code, I need to take the string from a database, explode it into the 2d array, edit values in the array and implode it back ready for storage in the same format. So specifically backwards in the same order as the existing script.
The code from the other post >>
$data = "i love funny movies \n i love stackoverflow dot com \n i like rock song";
$data = explode(" \n ", $data);
$out = array();
$step = 0;
$last = count($data);
$last--;
foreach($data as $key=>$item){
foreach(explode(' ',$item) as $value){
$out[$key][$step++] = $value;
}
if ($key!=$last){
$out[$key][$step++] = ' '; // not inserting last "space"
}
}
print '<pre>';
print_r($out);
print '</pre>';
The quoted code inserts separate array elements which just have a space as value. One can wonder what benefit those bring.
Here are two functions you could use:
function explode2D($row_delim, $col_delim, $str) {
return array_map(function ($line) use ($col_delim) {
return explode($col_delim, $line);
}, explode($row_delim, $str));
}
function implode2D($row_delim, $col_delim, $arr) {
return implode($row_delim,
array_map(function ($row) use ($col_delim) {
return implode($col_delim, $row);
}, $arr));
}
They are each other's opposite, and work much like the standard explode and implode functions, except that you need to specify two delimiters: one to delimit the rows, and another for the columns.
Here is how you would use it:
$data = "i love funny movies \n i love stackoverflow dot com \n i like rock song";
$arr = explode2D(" \n ", " ", $data);
// manipulate data
// ...
$arr[0][2] = "scary";
$arr[2][2] = "balad";
// convert back
$str = implode2D(" \n ", " ", $arr);
See it run on repl.it.

adding link values around each string

I have a php value coming back from my database as a string, like
"this, that, another, another"
And I'm trying to wrap a separate link around each of those strings, but I can't seem to get it to work. I've tried a for loop, but since it's just a string of information and not an array of information that doesn't really work. Is there a way to wrap a unique link around each value in my string?
The easiest way that I see to do this would be using PHP's explode() function. You'll find that it will become very useful as you start to use PHP more and more, so do check out its documentation page. It allows you to split a string up into an array given a certain separator. In your case, this would be ,. So to split the string:
$string = 'this, that, another, another 2';
$parts = explode(', ', $string);
Then use a foreach (again, check the documentation) to iterate through each of the parts and make them into a link:
foreach($parts as $part) {
echo '' . $part . "\n";
}
However, you can do this with a for loop. Strings can be accessed like arrays, so you can implement a parser pattern to parse the string, extract the parts, and create the links.
// Initialize some vars that we'll need
$str = "this, that, another, another";
$output = ""; // final output
$buffer = ""; // buffer to hold current part
// Iterate over each character
for($i = 0; $i < strlen($str); $i++) {
// If the character is our separator
if($str[$i] === ',') {
// We've reached the end of this part, so add it to our output
$output .= '' . trim($buffer) . "\n";
// clear it so we can start storing the next part
$buffer = "";
// and skip to the next character
continue;
}
// Otherwise, add the character to the buffer for the current part
$buffer .= $str[$i];
}
echo $output;
(Codepad Demo)
A better way is to do it like this
$string = "this, that, another, another";
$ex_string = explode(",",$string);
foreach($ex_string AS $item)
{
echo "<a href='#'>".$item."</a><br />";
}
First explode the string to get the individual words in an array. Then add the hyperlinks to the words and finally implode them.
$string = "this, that, another, another";
$words = explode(",", $string);
$words[0] = $words[0]
$words[1] = $words[1]
..
$string = implode(",", $words);
You can also use the for loop to assign hyperlinks that follow a pattern like this:
for ($i=0; $i<count($words); $i++) {
//assign URL for each word as its name or index
}

PHP: strip the tags off the value inside array_values()

I want to strip the tags off the value inside array_values() before imploding with tabs.
I tried with this line below but I have an error,
$output = implode("\t",strip_tags(array_keys($item)));
ideally I want to strip off the line breaks, double spaces, tabs from the value,
$output = implode("\t",preg_replace(array("/\t/", "/\s{2,}/", "/\n/"), array("", " ", " "), strip_tags(array_keys($item))));
but I think my method is not correct!
this is the entire function,
function process_data($items){
# set the variable
$output = null;
# check if the data is an items and is not empty
if (is_array($items) && !empty($items))
{
# start the row at 0
$row = 0;
# loop the items
foreach($items as $item)
{
if (is_array($item) && !empty($item))
{
if ($row == 0)
{
# write the column headers
$output = implode("\t",array_keys($item));
$output .= "\n";
}
# create a line of values for this row...
$output .= implode("\t",array_values($item));
$output .= "\n";
# increment the row so we don't create headers all over again
$row++;
}
}
}
# return the result
return $output;
}
Please let me know if you have any ideas how to fix this. Thanks!
strip_tags only works on strings, not on array input. Thus you have to apply it after implode made a string of the input.
$output = strip_tags(
implode("\t",
preg_replace(
array("/\t/", "/\s{2,}/", "/\n/"),
array("", " ", " "),
array_keys($item)
)
)
);
You'll have to test if it gives you the desired results. I don't know what the preg_replace accomplishes.
Otherwise you could use array_map("strip_tags", array_keys($item)) to have the tags removed first (if there are really any significant \t within the tags in the strings.)
(No idea what your big function is about.)
try mapping the arrays to strip_tags and trim.
implode("\t", array_map("trim", array_map("strip_tags", array_keys($item))));
Stripping the tags is easy as this:
$a = array('key'=>'array item<br>');
function fix(&$item, $key)
{
$item = strip_tags($item);
}
array_walk($a, 'fix');
print_r($a);
Of course, you can make whatever modifications you like to $item in the fix function. The change will be stored in the array.
For a multidimensional array use array_walk_recursive($a, 'fix');.
Looks like you just need to use array_map, since strip_tags expects a string, not an array.
$arr = array( "Some\tTabbed\tValue" => '1',
"Some value with double spaces" => '2',
"Some\nvalue\nwith\nnewlines" => '3',
);
$search = array("#\t#", "#\s{2,}#", "#\n#");
$replace = array("", " ", " ");
$output = implode("\t", preg_replace($search, $replace, array_map('strip_tags', array_keys($arr))));
echo $output;

How do I edit this text file using PHP?

I do have a text file having around 400k data in it. and its content is like this..
1,james
2,mathew
3,yancy
4,brandon
5,molner
6,nick
7,neil...and so on
How do I remove numbers and comas from this text file and keep only names?
Read the file into an array, where each array item is one line. Walk throught the array, find the first comma, and remove it and everything before. Then write it all back out again.
// Warning! Brain-compiled code ahead.
$arr = file('myfile.txt');
foreach ( $arr as &$val )
$val = substr($val, strpos($val, ',') + 1);
file_put_contents('myoutfile.txt', implode(PHP_EOL, $arr));
Note - no error checking. If a line lacks a comma, or comma is the last character, chaos ensues.
400k isn't incredibly much, so you should get away with this (tested):
foreach (file($path) as $line)
print preg_replace("~^[0-9]+\,(.*)~", "$1", $line);
Here is a perl one liner that do the job:
perl -i.save -pe 's/^\d+,//' test.txt
The original file will be saved in test.txt.save
This is tested and will return it as a list but you can save it to a database if you want:
$file_path='my_file.txt';
$file_handler = fopen($file_path, 'rt');
$doc = fread($file_handler, filesize($file_path)+1);
$rows = explode("\n", $doc);
$rows_array = array();
foreach ($rows as $row) {
$data = explode(",", $row);
$return_array[] = $data[1];
}
//print_r($return_array);
//you can save it to a db
echo '<ul>';
foreach($return_array as $value){
echo '<li>'.$value.'</li>';
}
echo '</ul>';

Categories