I am going to create an android dictionary application which goal is to translate my mother language (Zazaki) to Turkish.
I have 2 documents which have a format like below:
Zazaki to Turkish word docs
ban: ev ====> home
Turkish to Zazaki
ev: ban, çe ===> home
In my mind, first taking word before colon as key, after colon as value.
Then putting it into a database.
My question is:
"Do I have to do this operation for every time?
How can I make this database available for every download by not importing the word list documents into my database"?
First, if you have excel, it's quite easy to make a word document into a database , by splitting by ' ' and deleting the resulting columns you don't need. You can then export it, e.g. into a .csv file.
For your request, I would use the following pseudo-code as a guide for my code:
int currIndex = 0;
string key, value;
while(!EndOfFile){
currIndex = find('=');
key = getWordBeforeCurrentIndex();
currIndex = find('>');
value = getWordAfterCurrentIndex();
myDictionary.Add(key, value);
}
Make that into real code and voila - you got yourself an app parsing a document into a dictionary.
If you know that your document has an exact format like:
ev ====> home
word2 ===> translation2
word3 ===> translation3
You can of course leverage this and go
Dictionary myDict = new HashTable<string, string>();
InputStream wordDictionary = getResources().openRawResource(R.raw.wordDictionary);
DataInputStream myDIS = new DataInputStream(wordDictionary);
ArrayList<string> lines = new ArrayList<Lines>();
string currLine;
//Read document into arraylist:
while((myLine=myDIS.readline())!=null) list.add(myLine);
//Take each line, add left word as key, add right word as value:
foreach(line : lines){
myDict.add(line.substring(0, line.indexOf(" ")), line.substring(line.indexOf(" ", line.indexOf(" ")+1));
}
Related
Let's just say I have the variable String SRand = "KELRSFGLIU", what I want to do is create a word from the SRand variable and search for that word in the database. Or looking for data in a database based on the SRand variable, the words that need to be found do not have to be 10 characters but can be 3, 4 - 10 characters
can this be done?
As an illustration, I want to do something like this:
Ilustration 1:
String SRand = "KELRSFGLIU";
String Suggestion = "";
private void Create_Suggestion(){
//The magic for creating Sugeestion in here
//The result can be "FIRE", "GLUE", "FUR", or something else.
Suggestion = ???;
SearchData(Suggestion);
}
private void SearchData(String Suggest){
//Data Must Be Found
}
Any Idea?
I suggest you use trees in case you want to do that, more info can be found here
Updating a field contains period (.) is not working as expected.
In docs, nested fields can be updated by providing dot-seperated filed path strings or by providing FieldPath objects.
So if I have a field and it's key is "com.example.android" how I can update this field (from Android)?
In my scenario I've to set the document if it's not exists otherwise update the document. So first set is creating filed contains periods like above and then trying update same field it's creating new field with nested fields because it contains periods.
db.collection(id).document(uid).update(pkg, score)
What you want to do is possible:
FieldPath field = FieldPath.of("com.example.android");
db.collection(collection).document(id).update(field, value);
This is happening because the . (dot) symbol is used as a separator between objects that exist within Cloud Firestore documents. That's why you have this behaviour. To solve this, please avoid using the . symbol inside the key of the object. So in order to solve this, you need to change the way you are setting that key. So please change the following key:
com.example.android
with
com_example_android
And you'll be able to update your property without any issue. This can be done in a very simple way, by encoding the key when you are adding data to the database. So please use the following method to encode the key:
private String encodeKey(String key) {
return key.replace(".", "_");
}
And this method, to decode the key:
private String decodeKey(String key) {
return key.replace("_", ".");
}
Edit:
Acording to your comment, if you have a key that looks like this:
com.social.game_1
This case can be solved in a very simple way, by encoding/decoding the key twice. First econde the _ to #, second encode . to _. When decoding, first decode _ to . and second, decode # to _. Let's take a very simple example:
String s = "com.social.game_1";
String s1 = encodeKeyOne(s);
String s2 = encodeKeyTwo(s1);
System.out.println(s2);
String s3 = decodeKeyOne(s2);
String s4 = decodeKeyTwo(s3);
System.out.println(s4);
Here are the corresponding methods:
private static String encodeKeyOne(String key) {
return key.replace("_", "#");
}
private static String encodeKeyTwo(String key) {
return key.replace(".", "_");
}
private static String decodeKeyOne(String key) {
return key.replace("_", ".");
}
private static String decodeKeyTwo(String key) {
return key.replace("#", "_");
}
The output will be:
com_social_game#1
com.social.game_1 //The exact same String as the initial one
But note, this is only an example, you can encode/decode this key according to the use-case of your app. This a very common practice when it comes to encoding/decoding strings.
Best way to overcome this behavior is to use the set method with a merge: true parameter.
Example:
db.collection(id).document(uid).set(new HashMap<>() {{
put(pkg, score);
}}, SetOptions.merge())
for the js version
firestore schema:
cars: {
toyota.rav4: $25k
}
js code
const price = '$25k'
const model = 'toyota.rav4'
const field = new firebase.firestore.FieldPath('cars', model)
return await firebase
.firestore()
.collection('teams')
.doc(teamId)
.update(field, price)
Key should not contains periods (.), since it's conflicting with nested fields. An ideal solution is don't make keys are dynamic, those can not be determined. Then you have full control over how the keys should be.
I have a sql lite database in my android project that gets fed its data from a web service giving JSON. The JSON is straight forward, no tags. It simply has the rows of table data in the same field order as the table in the database.
JSON
[["123","ny","45"],
["456","nj","76"],
["778","ca","33"]]
SQL Lite Customer Table CustomerID,State,NumofItems
How can I import this into the database without the overhead of creating classes for each table etc.. some tables have over 50 fields.
I am using Xamarin if it somehow makes things easier
It depends upon what you mean by without a lot of coding and how many rows you are populating ;-)
Using dynamics and Json.Net you can use DeserializeObject to obtain an array of dynamics and loop through those array elements and construct a SQL Insert statement bypassing column names and class/model definitions of each table... Using dynamics is slower but unless you are populating a hundred thousand rows every import/app launch/.... this works fine...
This is how I am populating a bunch of tables in a case very much like yours to import numeric sequences for drawing SparkLines within RecyclerView/CardViews, I removed the error checking to simplify the answer:
Batteries_V2.Init();
var sqlConn = new SQLiteConnection("foobar.db");
sqlConn.CreateCommand("create table Customer (CustomerID INT PRIMARY KEY NOT NULL, State TEXT NOT NULL, NumofItems INT NOT NULL)").ExecuteNonQuery();
var jsonString = #"
[[""123"",""ny"",""45""],
[""456"",""nj"",""76""],
[""778"",""ca"",""33""]]"
;
dynamic jsonResponse = JsonConvert.DeserializeObject(jsonString);
sqlConn.BeginTransaction();
foreach (var item in jsonResponse)
{
string aBunchOfValues = "";
var noOfColumns = item.Count;
for (int i = 0; i < noOfColumns; i++)
{
var isString = !((string)item[i]).TryParse(out float n);
aBunchOfValues += $"{(isString ? '"' : ' ')}{item[i]}{(isString ? '"' : ' ')} {(i < noOfColumns - 1 ? ',' : ' ')}";
}
var sqlInsertString = $"INSERT INTO Customer VALUES ({aBunchOfValues});";
sqlConn.CreateCommand(sqlInsertString).ExecuteNonQuery();
}
sqlConn.Commit();
Note: This is using FKrueger's sqlite-net to provide the SQLiteConnection, CreateCommand and the transaction, this is on top of ESink's SQLitePCL.raw, adjust accordingly...
I am creating a database in Android, all was going nice, but when I was testing the queries retrieving the correct data I've got an error.
E/AndroidRuntime(14126): java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0
I know that means that there is no data matching the query, but the fact is that I inserted the data by query and it actually has a match. And the same query works with all the codes that doesn't have accents.
These are the queries for inserting the rows.
INSERT INTO "codigo" VALUES('A','PEATÓN');
INSERT INTO "codigo" VALUES('B','PEATÓN');
INSERT INTO "codigo" VALUES('C','PEATÓN');
So I did a query that gets the values of the field that I was replacing, like this:
String selectCode = "select distinct c.tipo from codigo c";
Cursor cursor = database.rawQuery(selectCodigo, new String[] {});
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
String codigo= cursor.getString(0);
codigos.add(codigo);
System.out.println(codigo);
cursor.moveToNext();
}
cursor.close();
return codigos;
And the result was this:
10-14 16:40:32.140: I/System.out(13716): PEAT�N
I have the text file in the /raw folder and I edited from the Eclipse so I make sure it wasn't the table export I did, but I have the same results.
This is the code that reads the file:
public int insertFromFile(SQLiteDatabase db,Context context, int resourceId) throws IOException {
// Reseting Counter
int result = 0;
// Open the resource
InputStream insertsStream = context.getResources().openRawResource(resourceId);
BufferedReader insertReader = new BufferedReader(new InputStreamReader(insertsStream));
// Iterate through lines (assuming each insert has its own line and theres no other stuff)
while (insertReader.ready()) {
String insertStmt = insertReader.readLine();
db.execSQL(insertStmt);
result++;
}
insertReader.close();
// returning number of inserted rows
return result;
}
How could I get that accent working?
I am using a lot of them, so, replacing the word is not a way out.
Please help, is the only thing I need to finish this project.
UPDATE:
Had the same problems two more times later. The first I fixed it by working with a .sql file coded in cp1525 and opened it in Eclipse with the default editor and find/replaced the wrong characters.
The last time I've got this error I made it the right way, and found that if you are working with SQLiteManager it imports files encoded in UTF-8 but it export files in ANSI, so I opened the file with Notepad++, change the enconding of the .sql file from ANSI to UTF-8 and it works fine, all the characters were shown fine.
The InputStreamReader constructor documentation says:
Constructs a new InputStreamReader on the InputStream in. This constructor sets the character converter to the encoding specified in the "file.encoding" property and falls back to ISO 8859_1 (ISO-Latin-1) if the property doesn't exist.
If the file is encoded in UTF-8, you have to tell the reader this.
in your SQLQueryString just add before
PRAGMA encoding = "UTF-8";
example
"PRAGMA encoding = \"UTF-8\"; INSERT INTO MYTABLE (mytablefield) VALUES ('value'); "
I've got a HTML code stored in string and I want to extract all parts that match the pattern, which is:
<a href="http://abc.pl/(.*?)/(.*?)"><img src="(.*?)"
(.*?) stands for any string. I've tried dozens of combinations and couldn't get it working. Can somebody show me a sample code, which extracts all matched data from a String and store it in variables?
Thanks in advance
Here is a solution using JavaScript. I hope this helps.
First, we need a working pattern:
var pattern = '<a href="http://abc.pl/([^/"]+)/([^/"]*)".*?><img src="([^"]*)"';
Now, the problem is that in JavaScript there is no native method or function that retrieves both all matches and all submatches at once, whatever the regexp we use.
We can easily retrieve an array of all the full matches:
var re = new RegExp(pattern, "g");
var matches = yourHtmlString.match(re);
But we also want the submatches, right? In my humble opinion, the simplest way to achieve this is to apply the non-greedy version of the same regexp to each match we obtained (because only non-greedy regexes can return submatches):
var reNonGreedy = new RegExp(pattern);
var matchesAndSubmatches = [];
for(var i = 0; i < matches.length; i++) {
matchesAndSubmatches[i] = matches[i].match(reNonGreedy);
}
Each element of matchesAndSubmatches is now an array such that:
matchesAndSubmatches[n][0] is the n-th full match,
matchesAndSubmatches[n][1] is the first submatch of the n-th full match,
matchesAndSubmatches[n][2] is the second submatch of the n-th full match, and so on.
Well, here's the sample:
Pattern pattern = Pattern.compile("patternGoesHere");
Matcher matcher = pattern.matcher(textGoesHere);
while (matcher.find())
{
// You can access substring here via matcher.group(substringIndex) [note they are indexed from 1, not 0]
}