I am making a question answering app and as a part of it, it needs to look at your previous questions which are stored in a SQL database and find the previous questions that has the most matching words and then it will take an attribute from the DB for that line.
I have been able to get it to produce an array of matching words for each row in the database. But I need a way of organizing those arrays to select the one with the most matches. here is the SQL and the PHP I have used to far.
$questions1 = $_GET['question'];
$questionsarray = explode(" ",$questions1);
The new question was turned into an array, below it will be compared against all other questions for match's
$sql = "SELECT * FROM records WHERE userid= '24.9.71.79'";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
$questionsasked = $row['old_questions'];
// turns old question into an array
$last_q_array = explode(" ",$questionsasked);
//finds matches between the old and new question
$intersectarray = array_intersect($last_q_array,$questionsarray);
It then uses array_diff() to clean out common words to help it focus on finding the true topic
$cleanedarray = array_diff($intersectarray ,$commonwords);
//prints the array if it find matches and sets the var
if(count($cleanedarray)>0) {
print_r($cleanedarray);
$desiredattri = $row[last_answer_type];
echo "<br />----------------<br />";
}
}
}
I'm using print_r just for testing. So it does a great job of producing a handful of arrays that show just the matching words. that looks something like this
Array ( [3] => card )
----------------
Array ( [3] => card [7] => work? )
----------------
Array ( [0] => find [2] => card [7] => work? )
So now I need to find a way to parse those arrays and find the one that has the most matches. I can use count() to count the matches in each array but still need to compare that number against the rest of the array counts and then use the attribute of the array with most matches.
You could try something like this. It will use the words themselves as array keys and the array value is the count.
$result = array();
foreach ($cleanedarray as $word) {
if (!array_key_exists($word, $result)) {
$result[$word] = 0;
}
$result[$word]++; // keep count using the word as key
}
I'm sure there might be other built-in PHP functions which could do this for you, but this was a quick-n-dirty way that came to me off hand.
Related
This question already has answers here:
in_array() and multidimensional array
(24 answers)
Closed 8 years ago.
I'm a newb and I got a problem with in_array...
So this is my array $allUsers (received by a SQL-Query for Usernames)
Array
(
[0] => Array
(
[name] => test
)
[1] => Array
(
[name] => test2
)
[2] => Array
(
[name] => admin
)
[3] => Array
(
[name] => kingChräbi
)
Now If a new member wants to register, I want to check in this array if it's already existent:
if(!in_array($username,$allUsers)){....
eventhough it is to when $username is NOT in $allUsers do .... it's just skipping to else also if the user is existing :(
$username is set before with
$username = $_POST['name'];
and working as it should (i can echo it without a problem, is exactly test or test2 without whitespace or anything)
I really looked around alot, but I can't find anything like my problem here... Could you please help me?
Thanks
although question itself is quite silly, as you have to realize what array you are working with, the quick solution, based on PDO tag, would be as follows: instead of fetchAll() use fetchAll(PDO::FETCH_COLUMN)
Or, rather you need to learn SQL as well, and find users not by means of selecting them ALL from database which makes no sense, but by asking a database to find a user for you
$stm = $pdo->prepare("SELECT * FROM table WHERE name=?");
$stm->execute(array($_POST['name']));
$user = $stm->fetch();
if ($user) { // <---HERE YOU GO
The in_array() does not work with multi-dimensional arrays. You better flatten your array and then do a search for the keyword.
$it = new RecursiveIteratorIterator(new RecursiveArrayIterator($arr)); //<-- Pass your array here
$new_arr = array();
foreach($it as $v) {
$new_arr[]=$v;
}
if(in_array('test',$new_arr))
{
echo "Exists !";
}
Working Demo
You are searching a 2-D array for a value under the key of "name".
Using array_map() or simple foreach loop should work -
$username = "admin";
$key = "name";
if(!in_array($username,array_map(function($v)use($key){return $v[$key];},$allUsers))){
echo "No found";
}else{
echo "Found";
}
If you are using:
While ($ row=mysql_fetch_assoc ($ result) {
$ data [] = $ row
}
Remove the [] to not create a multidimensional array.
I'm working on some stat tracking code for a game (yes, it's runescape. sue me).
I want to pull information from the high scores using an api which produces an array looking like this (captured using print_r)
Array
(
[getHiscore] => Array
(
[overall] => Array
(
[rank] => 61995
[lvl] => 2273
[totalxp] => 193310588
)
[attack] => Array
(
[rank] => 93406
[lvl] => 97
[totalxp] => 11747494
)
...and so on.
My question is how can i take what this api gives me and place it into a database table; I want to get an array such as this for a particular user and update their stats with it.
Would i use explode? It seems like the right idea to me but how would i actually use it to split the separate numbers and words?
My database is not totally realised yet, however each record will include a user name and then the level and total xp in each of 27 "skills". This almost certainly not best practice for database design but i'm as novice as they come so it's the best i can do.
You don't need to explode. It's an array and therefore it's already exploded. You need to iterate through it to build meaningful queries.
I'm not familiar with runescape so I don't know if your example is showing just the relevant fields of you need to discard some part. If it's the former, then you should try something like
$query="insert into stats_table (description, rank, lvl, totalexp) values (:description, :rank, :lvl, :totalext);";
$Statement = $DBConn->prepare($query);
foreach($fullArray as $description=>$subArray) {
$Statement->bindValue(':description',$description, PDO::PARAM_STR);
foreach($subArray as $key=>$value) {
$Statement->bindValue($key,$value, PDO::PARAM_STR);
}
$Statement->execute();
}
That will insert two rows containing
overall 61995 2273 193310588
attack 93406 97 11747494
PD: $DBConn is a PDO connection instance to whatever DB engine you're using.
Let's say this is all stored in the variable $ary:
$ary['getHiscore']['overall']['rank'] = 61995;
$ary['getHiscore']['overall']['lvl'] = 2273;
$ary['getHiscore']['overall']['totalxp'] = 193310588;
$ary['getHiscore']['attack']['rank'] = 93406;
$ary['getHiscore']['attack']['lvl'] = 97;
$ary['getHiscore']['attack']['totalxp'] = 11747494;
So, to get those values, it's:
$attackLevel = $ary['getHiscore']['attack']['lvl'];
If you
echo $attackLevel;
it would be 97.
Just pull the arrays out with a foreach loop and write some sql to insert the data. I don't know anything about your DB so if you want help there update your question please.
Simplest way to do this:
foreach($highscores as $highScoreType => $highScoreValues){
$rank = $highScoreValues['rank'];
$lvl = $highScoreValues['lvl'];
$totalXp = $highScoreValues['totalxp'];
//then it's up to you to put it into a table somehow.
}
$highScoreType will contain the values 'overall','attack',etc
This format of the foreach loop is extremely handy when iterating over an associative array (hash map/hash table, which is actually what all PHP arrays are underneath) will allow you to not only grab the value of the current pointed to entry, but also the key for that entry.
So, assume we have a single entry hashmap with key 'foo' and value 'bar'. If I want to show 'bar' I would simple
echo $map['foo'];//will output 'bar'
and if I put this into the above type of foreach loop
foreach($map as $fooKey => $barValue) {
echo $fooKey;//outputs 'foo'
echo $barValue;//outputs 'bar'
}
I have fields in mySQL which is currently being stored like this under the field "tags"
Shopping|Health & Beauty
Coffee|Shopping
What I'm trying to do is to loop through this to create a single dimension array and to grab only the unique values.
I have my query selecting DISTINCT tags from TABLE and run the loop like this:
while ($row_tags = mysql_fetch_assoc($r_tags)) {
$tags = $row_tags['tags'];
$imploded_tags[] = explode("|",$tags);
}
echo "<pre>";
print_r($imploded_tags);
The result from the print_r is showing it as a multidimensional array. I've tried to reexplode it and implode it in different ways, but I haven't been able to get any success. Is there a way that I can create this into a single dimension array? Not all tags will have an equal amount of tags separated by |, so I can't seem to get it to go with a function that I tried from another StackOverflow post. Any help would be greatly appreciated!
OUTPUT:
Array
(
[0] => Array
(
[0] => Shopping
[1] => Health & Beauty
)
[1] => Array
(
[0] => Coffee
[1] => Shopping
)
try this
while ($row_tags = mysql_fetch_assoc($r_tags)) {
$tags = $row_tags['tags'];
$tags = explode("|",$tags);
foreach($tags as $v){
$imploded_tags[] = $v;
}
}
I would do something like:
$imploded_tags = array_merge(explode("|",$tags), $imploded_tags);
}
$imploded_tags = array_unique($imploded_tags);
echo "<pre>";
print_r($imploded_tags);
See the manual on array_merge and array_unique.
However, I do think you are not using the right way to store your tags; they should be stored in a separate table as separate values.
What's going on is when you're fetching your rows from MySQL, you're essentially getting a bunch of data in an array in the first place, which is why you have to loop through them.
With your your implode function, you're taking a bunch of strings, then getting another array set and then appending that to an external array.
If you really wanted to get a single dimensional array without having this multidimensional thing going on, all you really need to do is utilize another loop within that loop.
$all_tags = array();
while ($row_tags = mysql_fetch_assoc($r_tags)) {
$tags = $row_tags['tags'];
$imploded_tags[] = explode("|",$tags);
for($i = 0; $i < count($imploded_tags); $i++) {
$all_tags[] = $imploded_tags[$i]
}
}
print_r($all_tags);
Assume that i have the following arrays containing:
Array (
[0] => 099/3274-6974
[1] => 099/12-365898
[2] => 001/323-9139
[3] => 002/3274-6974
[4] => 000/3623-8888
[5] => 001/323-9139
[6] => www.somesite.com
)
Where:
Values that starts with 000/, 002/ and 001/ represents mobile (cell) phone numbers
Values that starts with 099/ represents telephone (fixed) numbers
Vales that starts with www. represents web sites
I need to convert given array into 3 new arrays, each containing proper information, like arrayTelephone, arrayMobile, arraySite.
Function in_array works only if i know whole value of key in the given array, which is not my case.
Create the three empty arrays, loop through the source array with foreach, inspect each value (regexp is nice for this) and add the items to their respective arrays.
Loop through all the items and sort them into the appropriate arrays based on the first 4 characters.
$arrayTelephone = array();
$arrayMobile = array();
$arraySite = array();
foreach($data as $item) {
switch(substr($item, 0, 4)) {
case '000/':
case '001/':
case '002/':
$arrayMobile[] = $item;
break;
case '099/':
$arrayTelephone[] = $item;
break;
case 'www.':
$arraySite[] = $item;
break;
}
}
You can loop over the array and push the value to the correct new array based on your criteria. Example:
<?php
$fixed_array = array();
foreach ($data_array as $data) {
if (strpos($data, '099') === 0) {
$fixed_array[] = $data;
}
if ....
}
Yes i actually wrote the full code with preg_match but after reading some comments i accept that its better to show the way.
You will create three different arrays named arrayTelephone, arrayMobile, arraySite.
than you will search though your first array with foreach or for loop. Compare your current loop value with your criteria and push the value to one of the convenient new arrays (arrayTelephone, arrayMobile, arraySite) after pushing just continue your loop with "continue" statement.
You can find the solution by looking add the Perfect PHP Guide
I'm parsing some information using Xpath and it returns me a simple array.
$values = array();
Array
(
[0] => http://www.aaa.com/19364328526/
[1] => http://www.bbb.com/207341152011/
[2] => http://www.ccc.co.jp/1246623/
)
Is there any way I can parse through the array and only take certain URLs based on URL weighting? For example. If aaa.com exists, take only aaa.com. If not, check for ccc.co.jp, if that exists, take that only, etc.
I only know how to select from arrays when I know what is there $values[0]/[1]/etc, unfortunately the order of links in this array change and/or aren't present sometimes.
Any help would be much appreciated!
Thanks!
Tre
You can use in_array() to check if a value exists. I don't know exactly what you are trying to do, but here is an example. Do you know all the possible values that you might get back?
//List domains in priority order
$weighted = array('aaa.com','bbb.com','ccc.com');
$selected_url = '';
foreach($weighted as $check) { //start with highest priority
foreach($values as $url) { //loop through all URL's
if(strpos($url,$check) !== false) {
//If a url matches priority, return it. We are finished to exit both loops
$selected_url = $url;
break 2;
}
}
}
$selected_url should have the highest priority URL, or it will be empty if none of the urls were found.