I am using dotnetrdf and trying to parse some triples with NTriplesParser. I have my own handler RobHandler in which I process each triple in turn.
public class RobHandler : BaseRdfHandler
{
protected override bool HandleTripleInternal(Triple t)
{
string predicateUrl = ((BaseUriNode)(t.Predicate)).Uri.AbsoluteUri;
string value = t.Object.ToString();
}
}
This works fine but I want to get the object minus the language. My objects look like "Lincoln"#en. I could obviously write some code to remove the #en bit, but I'd rather use some library code rather than my own that hard-coded strings like #en. To do this I think I need to create a LiteralNode but there doesn't seem to be a way to get from a string which is what I have (my variable value) to a LiteralNode.
How can I extract just the textual value from an object string?
Actually I think I have the answer myself:
if (t.Object.NodeType == NodeType.Literal)
{
var node = (ILiteralNode)t.Object;
}
Related
I have lots of getters for localizations (they are coming from the json file for example) such as:
String get start {
return localizedValues[locale.languageCode]!['start']!;
}
String get hours {
return localizedValues[locale.languageCode]!['hours']!;
}
String get minutes {
return localizedValues[locale.languageCode]!['minutes']!;
}
String get seconds {
return localizedValues[locale.languageCode]!['seconds']!;
}
So I want to compound them since they use some common codes (I tried to create final someWord = commonCode; but It did not work, so I wanted to ask)
Now, If I want to reach them, I use myClass.of(context).start for example. So, in the end, I will reach using the same way but in the class which is above, I will not do any duplication If you help me. So, I need your help to avoid duplication.
I would recommend using a data class to hold localisation data instead of just a Map, or using a package such as i10n to do the translations for you.
There are a couple of ways you can shorten this code. For starters, you can extract localizedValues[locale.languageCode]! to its own getter, like this:
Map<String, String> get localeValues => localizedValues[locale.languageCode]!;
Then all your methods become a bit shorter:
String get seconds {
return localeValues['seconds']!;
}
Additionally, you can shorten your getters by removing the function body and using an arrow function instead, like I did above for the localeValues:
String get seconds => localeValues['seconds']!;
Do this for all your getters, and your code is now shorter.
You can use this method, and shorten the code:
String getTime(String languageCode, String time) {
return localizedValues[languageCode]![time]!;
}
getTime("1529", "seconds");
getTime("859", "mitutes");
getTime("9632", "hours");
In Rescript, one can define a Record in this format:
type record1 = {
a : String
}
but NOT:
type record2 = {
[a] : String
}
I am looking to write a record that compiles to JS like:
{
[Op.or]: [12,13]
}
The use case above comes from Sequelize, and the reference is here.
My current solution:
%raw(`{[Op.or]:[12,13]}`)
It's not entirely clear how you intend to interface with the Op construct, whether you can bind to it or not, but here's an example that does, and along with Js.Dict.t effectively produces the same output:
module Op = {
#val external or: string = "Op.or"
}
Js.Dict.fromList(list{
(Op.or, [12, 23])
})
It does not directly compile to the JS you want, however, which might be a problem if you rely on something that actually parses the source code. But short of that, I believe this should do what you ask for.
I've searched a lot but can't find a clear answer anywhere for string list -> enum.
I've got a list of strings that I want to turn into an enum that I can select from in Unity inspector.
Specifically, I'm trying to make an enum list of all the currently set-up Input buttons from project settings. I've got all the names, just don't know how to make it an enum or similar. Ideally showing up like a KeyCode variable in inspector.
Currently trying (and failing) with:
foreach (string s in names)
{
if (Enum.TryParse(s, true, out list))
Debug.Log(list);
else Debug.Log("FAILED");
}
"names" = static List<string> names;
"list" = static MyList list;
"MyList" = enum MyList { Null }
Returns "FAILED" 58 times for only 29 Input axis.
I want a simple solution, so if its not possible or relatively simple, I'll work out something else.
Code for getting the "names" list of strings (Works correctly):
var inputManager = AssetDatabase.LoadAllAssetsAtPath("ProjectSettings/InputManager.asset")[0];
SerializedObject obj = new SerializedObject(inputManager);
SerializedProperty axisArray = obj.FindProperty("m_Axes");
if (axisArray.arraySize == 0)
Debug.Log("No Axes");
for (int i = 0; i < axisArray.arraySize; ++i)
{
var axis = axisArray.GetArrayElementAtIndex(i);
var name = axis.FindPropertyRelative("m_Name").stringValue;
names.Add(name);
}
Normally you can do
foreach (string colorName in Enum.GetNames(typeof(Colors))) which will iterate the names of the enums.
In your code above you havent shown what list is, nor where names has come from. However.
enum Things
{
Item1 = 0,
Item2 = 1
}
You can get the name from string name = Enum.GetName(typeof(Things), (int)Things.Item2) and you can get values from names with int value = (int)Enum.Parse(typeof(Things), nameOfThing)
So depending on what you actually want in a list and what you start with, iterate through and pick the relevant one
I ended up making my own solution, since (and please correct me if I'm wrong) the TryParse() and Parse() methods appear to need the enum to already contain entries with the same name (or index int) as the string to parse. This defeats the purpose for me, since I am doing this because I don't have the names in there already.
My solution ended up being to switch to having a single string input variable instead of an enum, then use Odin Inspector's ValidateInput attribute to check (for spelling errors, and) if the input variable matches any of the string entries in my dynamic list of InputManager input names (which I update manually using Odin Inspector's Button attribute and the code in the original post).
It's slightly less clean than I wanted, but does the job, so I'm satisfied.
I know this is a very fundamental question but answer to this will solve many of my doubts.
val new_parent = ParentDetails(intent.extras.getString("name"),
intent.extras.getString("email"),
intent.extras.getString("parent_relation"),
intent.extras.getString("locationdata"))
println(new_parent.tostring())
The code above doesn't print the various fields and their values present in the class.
The ParentDetails is a model I have created with some fields that are initialized. The ParentDetails model:
class ParentDetails {
var parent_id: Int = 0
var parent_name: String = ""
var parent_email: String = ""
var parent_relation: String = ""
var parent_location: String=""
constructor(parent_name: String, parent_email: String, parent_relation: String,parent_location:String) {
this.parent_name = parent_name
this.parent_email = parent_email
this.parent_relation = parent_relation
this.parent_location = parent_location
}
public fun getparentId(): Int {
return parent_id
}
fun ParentDetailsprintme() {
println(parent_name)
println(parent_email)
println(parent_relation)
println(parent_location)
}
}
In fact, it prints null and accessing individual fields, it prints empty string(the way it was initialized).
How do we explain this?
As I understand your problem is that calling println(new_parent.tostring()) does not print what you would like to print in function ParentDetailsprintme.
First of all, you have a typo, the correct call would be new_parent.toString().
Note that it could have been simplified as println(new_parent).
It does not print that you defined in the ParentDetailsprintme method, as the method is not called.
What println(new_parent.toString()) prints, is actually the hashcode of the object, as this is the default behaviour of every object.
To make it work call it like println(new_parent.ParentDetailsprintme()) or override the toString() method for example as:
override fun toString() = "$parent_name $parent_email $parent_relation $parent_location"
then the following
val new_parent = ParentDetails("myName", "myEmail", "myParent_relation", "myLocationdata")
println(new_parent)
should print
myName myEmail myParent_relation myLocationdata
Kotlin's println function simply calls System.out.println(message) under the hood which will call String.valueOf() (e.g. String.valueOf(Object object) for objects, which will call the toString() method of the passed object).
/** Prints the given message and newline to the standard output stream. */
#kotlin.internal.InlineOnly
public inline fun println(message: CharArray) {
System.out.println(message)
}
Update ("Using data class method also works"):
If you make the class to be a data class:
data class ParentDetails(
val parent_id: Int = 0,
val parent_name: String = "",
val parent_email: String = "",
val parent_relation: String = "",
val parent_location: String = ""
)
and then you execute
val new_parent = ParentDetails(0, "myName", "myEmail", "myParent_relation", "myLocationdata")
println(new_parent)
you will receive as result
ParentDetails(parent_id=0, parent_name=myName, parent_email=myEmail, parent_relation=myParent_relation, parent_location=myLocationdata)
This is because data classes override the toString() function:
The compiler automatically derives the following members from all
properties declared in the primary constructor:
equals()/hashCode() pair;
toString() of the form "User(name=John, age=42)";
Did you check that you receive valid data from your intent.extras?
Also I suggest you use data class for your models.
It will look something like this:
data class ParentDetails(
var parent_id: Int = 0,
var parent_name: String = "",
var parent_email: String = "",
var parent_relation: String = "",
var parent_location: String = ""
)
You will be able to use it like this :
val new_parent = ParentDetails(
parent_name = intent.extras.getString("name"),
parent_email = intent.extras.getString("email"),
parent_relation = intent.extras.getString("parent_relation"),
parent_location = intent.extras.getString("locationdata")
)
println(new_parent.tostring())
As already mentioned, you have a typo. toString returns the hashcode of an object unless it's overridden to return something else. Look up the original implementation for more details.
By overriding the toString method, you change what it returns, and through that, what is printed when you print(someClass). DVarga showed that in their answer.
Data classes auto-generate a toString method containing the content of the class. So creating a data class is a shortcut to getting output containing the data.
The reason the method you had didn't work is because you didn't call it. if you call it instead of toString, you would get the data printed.
Also, toString is explicitly called when you print a class. You don't need to call print(someInstance.toString()), print(someInstance) is enough.
And while I'm writing an answer, you don't need to use secondary constructors in Kotlin. Primary constructors would shorten your code significantly, whether it's a data class or not. Also, you should look into naming conventions.
OK, what I'm trying to do is fairy complicated, but I'll try to explain.
Let's say we want (at compile-time) all derivedMembers of class someClass. Then we'd simply do :
const string[] methods = [__traits(derivedMembers,someClass)];
Now, how could we get someClass from "someClass"? (yep, its string representation).
Let me explain a bit more what I'm trying to do :
I want to create an "intermediate" function which takes a function name as an argument (along with a params array) and calls the appropriate function from a list of available static methods in a specific (predefined) set of classes. Like execute("someFunc",["one","two","three"]);.
Here's the full (test) code :
class Math {
static string noArgs(string[] s) { writeln(s); return ""; }
static string withOneArg(string[] s) { writeln(s); return ""; }
static string withTwoArgs(string[] s) { writeln(s); return ""; }
}
string cases()
{
string ret = "";
const string[] methods = [__traits(derivedMembers,Math)];
foreach (string s; methods)
{
ret ~= "case \"" ~ s ~ "\": return Math."~s~"(params);";
}
return ret;
}
string execute(string what, string[] params)
{
switch (what)
{
mixin(cases());
default: break;
}
return "";
}
The trouble with the above code is that it only looks for methods in Math. How could I change it, in an elegant D-friendly way, so that it'll go through an array of classes like [Math,String,SomethingElse] -- it doesn't have to be variable (we need it at compile-time anyway)?
UPDATE:
Tried something along the lines of :
const string[] methods = [__traits(derivedMembers,mixin("Math")];
but it complains that Cannot interpret Math at compile time.
UPDATE 2:
Also, tried using Object.factory("Math") but it's still not working. (Perhaps I'm just creating an instance of the Math class?)
Let me rewrite this to show you some cool tricks:
import std.stdio;
class Math {
static string noArgs(string[] s) { writeln(s); return ""; }
static string withOneArg(string[] s) { writeln(s); return ""; }
static string withTwoArgs(string[] s) { writeln(s); return ""; }
}
class String {
static string oneArg(string[] s) { return null; }
}
string execute(string what, string[] params) {
import std.string;
auto parts = what.split(".");
auto className = parts[0];
auto methodName = parts[1];
import std.typetuple;
switch(className) {
default: assert(0, "unknown class");
foreach(possibleClass; TypeTuple!(Math, String)) {
case possibleClass.stringof:
switch(methodName) {
default: assert(0, "unknown method");
foreach(memberName; __traits(derivedMembers, possibleClass)) {
case memberName:
return __traits(getMember, possibleClass, memberName)(params);
break;
}
}
break;
}
}
assert(0);
}
void main() {
execute("Math.withOneArg", ["cool"]);
execute("String.oneArg", ["cool"]);
}
Notice that there are no mixin expressions used at all. Instead of getting an instance of the class from a string, I just made a TypeTuple of all the classes I wanted to use. This is preferable to mixin because then it is less likely to find name classes when used in different scopes; if possibleClasses were a compile-time parameter to execute from a different module, the list of classes would still work, whereas the list of strings would see undefined identifier errors because the library module doesn't import your user module.
Another mixin I removed was the one to generate the cases. This looks insane, but is allowed in D: if you have a compile-time foreach (that is, a foreach over a built-in tuple of some sort, e.g. TypeTuple, template argument lists, the results of __traits...) you can actually put case statements inside them!
So, all you have to do is write a regular switch statement on the run time variable you want to compare against, put the foreach inside it looping over the compile-time stuff you're searching for, case that_loop_var: and boom, you're in business.
Similarly, I used __traits(getMember) rather than a mixin string to call the method. This solution will help avoid name clashes and IMO is cleaner code. It can also potentially handle overloads, if wanted (with __traits(getOverloads) instead of __traits(getMember), you can loop over each one then and match the parameter types).
Finally, nesting switches inside other case statements is allowed. If you need to break out of an outer loop or switch and don't want ambiguity, you can label loops and switches and use break label_name_here; to specify which one you want to break from. Ditto for continue with nested loops.
BTW you could also automatically generate the wrapper functions that convert string[] to other types of arguments if you dove into the std.traits stuff. I wish my book was out already, I wrote about this at some length in there and don't feel like writing it all right now but if you look at std.traits.ParameterTypeTuple and ReturnType in the same module that will get you started if you wanna try it.