DXL matches Method for exact string comparison - matching

I am trying to link objects between two modules with a DXL script. In the source object, a string is read. If the string exists in the target module --> Link the objects. Code is working so far. My Problem is, like when my source module has a string "valObject" the matches method is true if my target string contents "valObjectColor". But the matches function should give a false-value.
The heart of the code is below.
Is there any possibility to check for the exact match? I couldnĀ“t find any options in the DXL Reference book.
// two nested loops, that go throught every object in both modules and compare given strings
for srcObject in currModule do
{
if(srcObject."Typ" "" == "Testparameter")
{
// save testparameter in variable
string parameter = srcObject."Object Text" ""
//iterate throught the targetModule
for trgtObject in trgtModule do
{
string t = trgtObject."Parameter (Text)"
if(matches(parameter,t))
{
srcObject -> trgtObject
counter ++
}
}
}
}
Kind regards
Oguz

Maybe you can clarify, but I'm a bit confused why you're using the matches() function:
if(matches(parameter,t))
matches(a, b) is not used for exact matches but for regular expression matches in your string b. Where string a is your regular expression.
If you want an exact match, you can just perform a simple comparison.
if (parameter == t)

Related

kotlin "contains" doesn't work as expected

I am working with a method which filters the preferences which match with the ids, I am using the contains method, but even though the values are the same, the contains is showing a false in each iteration. The method looks like:
private fun filterPreferencesByIds(context: MyPodCastPresenterContext): List<FanPreferences> {
return context.preferences?.filter {
context.ids.contains(it.id)
}
}
The values of the arrays are:
for the context.ids:
"B52594F5-80A4-4B18-B5E2-8F7B12E92958" and "3998EDE7-F84B-4F02-8E15-65F535080100"
And for the context.preferences:
But even though, when the first and the final ids have the same id value as the context.ids, the contains is false in the debug. I think it could be related with the types in the context.ids rows Json$JsonTextNode. Because when I did the same with numeric values hardcoded the compare is successful.
Any ideas?
Thanks!
If the type of FanPreferences.id is String and the type of context.ids list element is JsonTextNode, you won't find an element equal to the given id string, because it's not of String type.
Try mapping your context ids to the list of strings before filtering:
val ids = context.ids.map { it.toString() }.toSet()
return context.preferences?.filter {
ids.contains(it.id)
}
Note that calling toString() on JsonTextNode might be not the best way to get the string data from it. It's better to consult the API documentation of that class to find it out.

Check if a string contains all other strings

I am trying to code a part of a software where I try to show the results that match search criteria.
I have a textbox where I can type one or more words I want to search and a listview that contains 4 different columns and a dozen rows. The idea is that each listview row contains lots of words and I want to see only the rows that contain all the words I have typed in the textbox. I have finished the code that searches for one term only. The problem I am having is that I don't fully understand how to do the same, but using multiple terms instead of one term only.
In the textbox, I write the words I want to search separated by a space. I have a variable where I keep the whole content of the listview row separated by : (example => col1row1content:col1row2content:col1row3content,etc). Summarizing, I want to check if a string (the full content of a row) contains all other strings (each word I have typped in the textbox).
This is the code I have implemented:
Dim textboxFullContentArray As String() = textboxSearch.Split(New Char() {" "c})
Dim Content As String
Dim containsAll As Boolean = False
Dim wholeRowContent(listviewMain.Items.Count - 1) As String ' each index of the array keeps the entire row content (one array contains all 4 cells of the row)
' wholeRowContent contains in one index the entire content of a row. That means,
' the index contains the 4 cells that represent an entire row.
' The format is like "rowData1:rowData2:rowData3:rowData4" (omitted for simplicity)
For Q As Integer = 0 To listviewMain.Items.Count - 1
For Each Content In textboxFullContentArray
If wholeRowContent(Q).ToLower.Contains(Content) Then
containsAll = True
' rest of the code...
ElseIf Not wholeRowContent(Q).ToLower.Contains(Content) Then
containsAll = False
Exit For
End If
Next
Next
But of course, this code is showing false positives and I think it's not a good solution. I think it must be much easier and I am overcomplicating the concept.
I am using VB.Net 2013
You can determine whether a String contains all of a list of substrings with a single line of code:
If substrings.All(Function(s) str.IndexOf(s, StringComparison.OrdinalIgnoreCase) >= 0) Then
Notice that I have actually implemented a case-insensitive comparison, rather than using ToLower or ToUpper.
It may not seem as neat to call IndexOf rather than Contains but guess what: Contains actually calls IndexOf internally anyway:
public bool Contains(string value)
{
return this.IndexOf(value, StringComparison.Ordinal) >= 0;
}
You can write your own extension methods if you want a case-insensitive Contains method:
<Extension>
Public Function Contains(source As String,
value As String,
comparisonType As StringComparison) As Boolean
Return source.IndexOf(value, comparisonType) >= 0
End Function
Your If/Else looks like it could be simplified. I would set your containsAll value to true outside the nested loops, and only if you encounter a "Content" in "textboxFullContentArray" that is not contained in wholeRowContent(Q) you set containsAll to false, otherwise do nothing.
Also, one way to see what's going on is to print statements with the values that are being compared throughout your function, which you can read through and see what is happening at runtime when the false positives occur.
After some hours looking for a simple and effective solution (and trying different codes), I have finally found this solution that I adapted from: Bad word filter - stackoverflow
For Q As Integer = 0 To listviewMain.Items.Count - 1
If textboxFullContentArray.All(Function(b) wholeRowContent(q).ToLower().Contains(b.ToLower())) Then
' my code
End If
Next

proper way to get the last element of the array when split is used on the string within JSON

I have a JSON response from the server and I am using map to use only necessary key:valuepairs in Angular (typescript) that will be used to display on the Frontend side.
here bizStep is actually according to a standard (EPCIS) and has the following value:
urn:epcglobal:cbv:bizstep:receiving
I only want to the user to read receiving hence I used split and obtained the last value of the array to display the value.
The logic is shown below:
this.serv.getEpcisInfo(code) // HTTP GET Service from Angular
.subscribe(res => {
this.data = res.map(el => { // map only some key value pairs now!
return {
'business step': el.bizStep.split(':')[el.bizStep.split(':').length - 1]
});
});
But it is observed that in order to obtain the overall length of the splited string array I have to write the expression el.bizStep.split(':') twice.
Is there a shorthand or elegant expression to obtain the last string value of the array.
I did try to use el.bizStep.split(':')[-1] however this expression failed and did not provide me any value.
You can use Array.pop since you don't need to preserve the result of the split, i.e. el.bizStep.split(':').pop().
A more general approach would be to use an anonymous function, e.g.:
(s => s[s.length-1])(el.bizStep.split(':'))
You could modify this to get elements other than the last. Of course, this example has no error checking on the length or type of el.bizStep.

How to convert ASCII integers to string in Streambase?

I am using streambase, and have created a map to convert incoming integers (0-255) into character codes. Right now, I'm using manual if/else statements. For example:
if (message_code == '106') then
message_code = 'J'
else if (message_code == '110') then
message_code= 'N'
However, I'd like to just use this more generally. Searching Streambase Studio help didn't really provide anything as far as I could tell. I know this can be done in Java, but would probably require calling a java external function. I'm not so competent at this, so am a bit lost.
Is there a better way to do this in StreamBase?
Initial investigations confirm that the StreamBase Expression Language or built-in Functions don't have an obvious way to convert ints representing ASCII character values into a one-character string corresponding to the ASCII value. If there's some non-obvious trick I discover later, I'll come back and edit this answer.
I definitely wouldn't use a 255-clause if/then/else expression!
I would probably use a Java function and here is an example I've lightly tested:
package example;
public class ASCIIIntToString {
public static String ASCIIToString(Integer a) {
if (a == null || a < 0 || a > 255) {
return null;
} else {
return Character.toString((char) (int) a);
}
}
}
And the custom-function declaration to drop into your sbd.sbconf would look like this:
<custom-functions>
<custom-function alias="ASCIIToString"
args="auto"
class="example.ASCIIIntToString"
language="java"
name="ASCIIToString"
type="simple"/>
</custom-functions>
But if you would rather not drop into Java and stay in EventFlow then two methods come to mind:
Load a CSV file with int -> string mappings in them into a Query Table and dto a lookup with Query Read operator, perhaps using the Initial Contents tab to reference the CSV file since ASCII isn't going to change anytime soon.
Create a list constant called, say, ASCII, that has all the strings you want to convert to and index the list by the int. For example, in a Map operator do Add c ASCII[i], and add some bounds checking logic (perhaps in a user function).
Disclosure/Disclaimer: I am an employee of TIBCO Software, Inc. Opinions expressed here are my own and not TIBCO's.

How do I return a string as a one element array reference in Perl?

I'm new to Perl, and this thing has got me stuck for far too long...
I want to dump a readable representation of the object itself from inside a function (I'm trying to debug something, and I'm doing this by returning an array reference which the caller expects, but containing an object dump rather than human readable text as per normal) so in my package I have:
use Data::Dumper;
sub somefunctionName{
my $self = shift;
my $d = Dumper($self);
my #retval = ();
push(#retval, $d);
return \#retval;
}
This is giving me the error "Can't use string ("the literal object dump goes here") as a HASH ref while "strict refs" in use"
I can't for the life of me figure out a way to make the error go away, no matter how I mess with the backslashes, and what I've done above looks to me like exactly what every online tutorial does... But I'm obviously missing the point somewhere.
What am I doing wrong?
According to the documentation
Dumper(LIST)
Returns the stringified form of the values in the list, subject to the configuration options below. The values will be named $VAR n in the output, where n is a numeric suffix. Will return a list of strings in a list context.
You should be able to do
#retval = Dumper($self);
return \#retval

Resources