Accessing specific Grails Params in controller - java

This is probably a simple one and more Java related than grails but I'm a bit lost and not sure where to even start looking on this, I've googled about but am not really sure what I'm after, so would appreciate a pointer if possible please!
In the grails app I have a form which I save, all well and good. In the controller I can see the list of params it returns via a simple println and when I want to find a specific value currently I do a params.each and then compare the key to a pre defined string to find the one I want, my question is: -
Can I, and how would I, specifically say "get me the value of the parameter with the key "banana", rather than having to loop through the whole list to find it?
Also is there a way of creating a new set of secondary params, or just another plain old dictionary item (is that the right term?) where I use a regular expression to say "give me all the items whose key match the pattern "XYZ"?
It probably doesn't make much difference speed wise as the params are never that big but it'd be nice to make things more efficient where possible.
Any feedback much appreciated!

For a first question, to get 'banana' parameter you have to use:
params.banana
For second, find all with regexp:
def matched = params.findAll { it.key =~ /XYZ/ }
//or
Pattern p = ~/XYZ/
def matched = params.findAll { p.matcher(it.key).matches() }

There's a params object you can use. Eg with someurl.com?myparam=test you can access it with "params.myparam"
More information over here: http://grails.org/doc/2.2.x/ref/Controllers/params.html

Related

fail to create a string with inner properties

I have a map prop call row which is Map (string , string), now what I want is to add to it a Link key val to the map, but from some reason I get fail when im trying to do s"=HYPERLINK(\"${tmpLink}\")", which suppose to work cause if s"=HYPERLINK(\"www.something.com\")") it works, so obviously there is something wrong with the ${tmpLink} but I dont understan why, you can see here how I set up tmpLink which I checked and is a string:
val tmpLink = s"https://bla.com/${invID.replaceAll("[\"=]", "")}"
row ++ Map("Link" -> s"=HYPERLINK(\"${tmpLink}\")")
and the error I get is:
value $ is not a member of (String, String)
someone knows whats the issue?
Here is issue you are facing https://issues.scala-lang.org/browse/SI-6476, essentially, escapes don't work with string interpolation.
It's unfortunate but for most cases you can use the triple quote syntax as a work around:
s"""=HYPERLINK("${tmpLink}")"""
And it will work.

Bukkit Minecraft setIngredient Material id colon issue

I am trying to use a full id of a block in the getmaterial part of the code below. this does not work any way that i try.
I cannot find any documentation supporting this issue of handling an id which contains a 'colon :' .
Snip: (Example the 5758:6 below does not work and the string name neither.)
emerald.setIngredient('L', Material.getMaterial("5758:6"));
Material.getMaterial(406) //this is expecting an integer so i cannot give it two numbers
Material.getMaterial(406:1) //this fails as is expecting int
Assuming that emerald is a ShapedRecipe object (since you're using the setIngredient(char, Material) method), then you can also use the setIngredient(char, MaterialData) method instead. You could construct the MaterialData object you want using the (deprecated...) MaterialData(int, byte) constructor. Your new code would look like:
emerald.setIngredient('L', new MaterialData(5758, 6));
The colon in the "full id of a block" is just separating the "id" and "data" values. I think this will do what you're looking for, but if not, let me know so I can clarify.
I don't think you're supposed to be dealing with that number colon thing. Instead, if you want to get to, say, the BRICK material, use Material.BRICK or Material.valueOf("BRICK"). If you want to find the name of a Material m, use m.name() which returns a String.

Java - Mapping a description to a word with Map/HashMap

I'm working on a small project in which I want the following to happen: I want to be able to give descriptions to words in such a way that I am able to get both pieces of information later on. Using a String array seems like it would be time consuming, and, by the way I'm interpreting what I'm reading, using the following piece of code only gives me the second written information, which is "Example Description.", because it maps the second value to the first "value" (which is a "key").
Map<String, String> exampleDictionaryThing = new HashMap<String, String>() {{
put("Example Word", "Example Description.");
}};
Just to make sure I'm understood, as English isn't really my best language, I'm trying to make a bunch of dictionary-like things where I'm able to grab both pieces of information, the two pieces of info. being a word and a description for it, but doing a bunch of String array's would A) take a lot of time and B) would be, what seems to me, an incredibly inefficient way of going about this issue.
Anybody have any ideas?
Update #1
I knew my wording would cause confusion; sorry xD. From what I've read on how I'm going about this, the line of code I've given above only allows me access to the "Example Description." line if I call the get() function. What I need is something to store two Strings and give me access to both (hopefully) without using a String array. My question is: How would I go about storing two Strings in that fashion?
If you have
HashMap<String, String> mp = new HashMap<String, String>();
which is properly populated (basically in the way you described), you can do the following in order to iterate through it (this way you have both the key and the value in your loop):
for (String word : mp.keySet()){
System.out.println("Word: [" + word + "]; Word Description: [" + mp.get(word) + "].");
}
If you want to "get both pieces of information later on" as you say, maybe you should take a look at Guava's BiMap. This data structure would allow you to recover the description given the word, or the opposite.
http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/BiMap.html

Manipulating Strings on Arrays

I'm still new to Java and I would like to understand Strings and Arrays so I got this idea of manipulating elements and place them according to my objective. The objective is that there will be Array of Strings "ABBCCCBBAA" and the "AA","BB" must be replaced into "A" , "BA","AB" into CC. "CC","BC" into B. I basically have no idea how to make it happen but I know it must have Arrays of String. Please help
Regular expression can be very handy for you. Code bellow can do, your job with the use of regular expression:
String mainStr = "ABBCCCBBAA";
Pattern p = Pattern.compile("(AA)|(BB)|(BA)|(AB)|(CC)|(BC)");
Matcher m = p.matcher(mainStr);
while (m.find()) {
String matchedStr = m.group(0);
if("AA".equals(matchedStr) || "BB".equals(matchedStr)){
mainStr = mainStr.replaceFirst(matchedStr,"X");
}
else if("BA".equals(matchedStr) || "AB".equals(matchedStr)){
mainStr = mainStr.replaceFirst(matchedStr,"Y");
}
else if("CC".equals(matchedStr) || "BC".equals(matchedStr)){
mainStr = mainStr.replaceFirst(matchedStr,"Z");
}
}
mainStr = mainStr.replaceAll("X","A").replaceAll("Y","CC").replaceAll("Z","B");
System.out.println(mainStr);
Above code will handle your case of multiple occurrence of same pattern in a given string like:
ABBCCCBBAABBBBAA
will generate output:
CCBBAAAAA.
I am assuming that by "array of strings" you mean:
String[] myvariable = new String[number];
myvariable[0] = "ABBCCBBAA";
myvariable[1] = "some_other_string";
If you are new to Java I suggest you read a beginner's book like Head First Java and also look into java documentation; you don't even have to go that far if you are programming with a decent IDE, like Netbeans (thanks to its intelli-sense feature) is a source of documentation for what you seek (meaning that you can look at all the methods available for a string, read what they do, and see if they can help accomplish what you need).
I am assuming (from what you have said) that you want to replace "AA" for "A", and from that result replace "BB" for "BA", and from that result replace "AB" into "CC", and from that result "BC" into "B".
The code I am posting is REAL simple, and it will only work for this particular case (as I have understood it), if you want to create a method that does this for any string, you need to change some things, but I'll leave that to you.
String[] yourArrayOfStrings = new String[1];
yourArrayOfStrings[0] = "ABBCCBBAA";
String resultOfReplacement= yourArrayOfStrings[0].replaceFirst("AA", "A");
System.out.println(resultOfReplacement); //debugging purposes
resultOfReplacement = resultOfReplacement.replaceFirst("BB", "BA");
System.out.println(resultOfReplacement); //debugging purposes
resultOfReplacement = resultOfReplacement.replaceFirst("AB", "CC");
System.out.println(resultOfReplacement); //debugging purposes
resultOfReplacement = resultOfReplacement.replaceFirst("BC", "BB");
System.out.println(resultOfReplacement); //debugging purposes
The only reason why I created a String[] was because that's what you stated in your question, otherwise I would have simple created a String variable like I did with resultOfReplacement. To access the first element in an array you do arrayVariable[index]. Here I use the replaceFirst function that comes with Java for variables of type String. If you look the method up, it'll tell you that it will look for the first match of the first parameter and replace it with the second parameter.
The System.out.println I have added are for debugging purposes, so you can see on the console what is clearly happening with each replacement. So, the first time I call replaceFirst(...) on the original string which is a[0].
This will happen:
The method will look in "ABBCCBBAA" for the FIRST AND ONLY THE FIRST time "AA" appears and replace it with "A". The result is "return" and you must assign it to a variable if you want access to it to do more actions upon it. In this case, I assign it to a new String variable. You could have just assigned back to a[0], which is likely what you want. (You'd do so like this: a[0]=ourArrayOfStrings[0].replaceFirst("AA", "A");)
For the second replacement, the method will look in "ABBCCBBA" for the first time "BB" appears and replace it for "BA".
See the pattern? This is just a start, and depending on what you want you might need other methods like replaceAll().
Most IDEs will tell you what methods are available for a variable when you access it via ".", so that when you are typing " variablename. " right at that moment a list of methods available for it should appear, if they donĀ“t you can go ahead and do a shortcut like ctrl+space for it to appear and navigate through the methods via the arrow keys so you can read what they do (at least for Eclpise and Netbeans, while programming in Java, it works). Documentation is power!

Lucene/Solr for approximate (company) name matching

I have a question regarding Lucene/Solr.
I am trying to solve a general (company) name matching problem.
Let me present one oversimplified example:
We have two (possibly large) lists of names viz., list_A and list_B.
We want to find the intersection of the two lists, but the names in the two lists may not always exactly match. For each distinct name in list_A, we will want to report one or more best matches from list_B.
I have heard that Lucene/Solr can solve this problem. Can you tell me if this is true? If it is, please point me to some minimal working example(s).
Thanks and regards,
Dibyendu
You could solve this with Lucene, yes, but if you just need to solve this one problem, creating a Lucene index would be a bit of a roundabout way to do it.
I'dd be more inclined to take a simpler approach. You could just find a library for fuzzy comparison between strings, and iterate through your lists and return only those under a certain threshold of similarity as matches.
org.apache.commons.lang3.StringUtils comes to mind, something like:
for (String a : alist) {
for (String b : blist) {
int dist = StringUtils.getLevenshteinDistance(a,b)
if (dist < threshold) {
//b is a good enough match for a, do something with it!
}
}
}
Depending on your intent, other algorithms might be more appropriate (Soundex or Metaphone, for instance)
SOLR can solve your problem. Index the list_B in SOLR. Now do a search for every item in list_A in SOLR, you will get one or more likely match from the list_B.
You need to configure analyzers and filters for the field according to your data set and what kind of similar result you want.
I am trying to do something similar, and I would like to point out to the other commenters that their proposed solutions (like Levenshtein Distance or Soundex) may not be appropriate, if the problem is matching of accurate names, as opposed to mis-spelled names.
For example: I doubt either one is much use for matching
John S W Edward
with
J Samuel Woodhouse Edward
I suppose it is possible, but this is a different class of problem than what they were intended to accomplish.

Categories