StringTemplate 3: how to filter a list? - stringtemplate

How can I remove specific elements from a list(=multi-valued-attribute) using a map? For example, let's say I want to filter out all b's in a given list:
<["a", "b", "c", "b"]: {<table.(it)>}; separator=",">
table ::= ["b":, default: key]
The desired outcome would be "a,c" but the actual result is "a,,c,"
The thing is that the map successfully turn b's into nulls, but then they're wrapped in an anonymous template {} and become non-null values. So they won't go away with strip() function, either.
So the question is, would it be possible to filter a list using a map by slightly modifying the code above?
update
I've found a workaround:
filter(it) ::= "<if(it)><it><endif>"
<["a", "b", "c", "b"]: {<table.(it)>}: filter(); separator=",">
This gives the result I wanted: a,c

Might not want to filter in your template, but nonetheless, could be a bug.
Ok, i checked it out. That gives empty not null so it thinks it's an item. ST treats false conditionals same way: empty not null. I think you need to filter in model.

Related

Filtering by a second column removes the filter from the first column, Ag Grid, Vue. How can it be avoided?

Filtering by a second column removes the filter from the first column, Ag Grid, Vue. How can it be avoided?
I would like to be able to filter by more than one column.
I am using the server side rendering. I found out the framework code which is responsible for checking if there is a filter applied (and if this code piece tells that a filter is not applied, then the respective filter gets removed):
SetValueModel.prototype.isFilterActive = function () {
return this.filterParams.defaultToNothingSelected ?
this.selectedValues.size > 0 :
this.allValues.length !== this.selectedValues.size;
};
In my case I did not set the defaultToNothingSelected, it is undefined, so it results in a falsy value. But since I update my set filter values after running the filter, the this.allValues.length becomes equal to the this.selectedValues.size, which results in the isFilterActive returning false.
So far the two solutions I see are to either set the defaultToNothingSelected to true or do not remove the available filter values after the filtering was done. I remove them using the api.getFilterInstance(colId).setFilterValues(values).
By removing the filter values I mean the following:
A column has the a, b and c values. I filter by a. Now I set the available filter values to be only a. Probably I should not be doing that.
I still hope to find a cleaner solution, so let the question hang here.

How to chain filter expressions together

I have data in the following format
ArrayList<Map.Entry<String,ByteString>>
[
{"a":[a-bytestring]},
{"b":[b-bytestring]},
{"a:model":[amodel-bytestring]},
{"b:model":[bmodel-bytestring]},
]
I am looking for a clean way to transform this data into the format (List<Map.Entry<ByteString,ByteString>>) where the key is the value of a and value is the value of a:model.
Desired output
List<Map.Entry<ByteString,ByteString>>
[
{[a-bytestring]:[amodel-bytestring]},
{[b-bytestring]:[bmodel-bytestring]}
]
I assume this will involve the use of filters or other map operations but am not familiar enough with Kotlin yet to know this
It's not possible to give an exact, tested answer without access to the ByteString class — but I don't think that's needed for an outline, as we don't need to manipulate byte strings, just pass them around. So here I'm going to substitute Int; it should be clear and avoid any dependencies, but still work in the same way.
I'm also going to use a more obvious input structure, which is simply a map:
val input = mapOf("a" to 1,
"b" to 2,
"a:model" to 11,
"b:model" to 12)
As I understand it, what we want is to link each key without :model with the corresponding one with :model, and return a map of their corresponding values.
That can be done like this:
val output = input.filterKeys{ !it.endsWith(":model") }
.map{ it.value to input["${it.key}:model"] }.toMap()
println(output) // Prints {1=11, 2=12}
The first line filters out all the entries whose keys end with :model, leaving only those without. Then the second creates a map from their values to the input values for the corresponding :model keys. (Unfortunately, there's no good general way to create one map directly from another; here map() creates a list of pairs, and then toMap() creates a map from that.)
I think if you replace Int with ByteString (or indeed any other type!), it should do what you ask.
The only thing to be aware of is that the output is a Map<Int, Int?> — i.e. the values are nullable. That's because there's no guarantee that each input key has a corresponding :model key; if it doesn't, the result will have a null value. If you want to omit those, you could call filterValues{ it != null } on the result.
However, if there's an ‘orphan’ :model key in the input, it will be ignored.

DMN Feel multiple Not Equals (!=)

I am reaching out to inquire about a challenge with DMN FEEL Logical Operator not equals.
Basically we are not getting a correct result when placing multiple Not Equals (!=) in a single field. From the attached example, we basically placed a condition in the 3rd column where if the Input.CallPurpose.Code is not equals to 2 or 1 - !="2", !="1" - then it should hit that row and return the output, but if we pass "2" or "1" then it should skip this row and try to hit the following rows accordingly.
In our case, If we pass (2) It hits the first operator (!= 2) and will skip the row which is the expected result; however if we pass (1) it will not compare to the second (!=) and it will not skip the row which is the incorrect result
If we pass a single != it works
Any help at this point would be much appreciated
Thanks
Possibly the most idiomatic way to do this, is to do something like:
not("B", "A")
So you want that if you supply either "A" or "B" it would match the first row.
Example supplying C:
In this case matches the first row because C is not A, not B.
Example supplying A:
In this case A is matched in the first row using basic unary tests.
If you wanted a generalized extended unary test you could write
not( ? in ["A", "B"])
too.
For future reference, this was solved by using the below syntax:
!=["option 1", "option 2", "option 3"]

How to get the equivalent of combinig [contains] and [in] operators in the same query?

So I have a field that's a multi-choice on the Directus back end so when the JSON comes out of the API it's a one-dimensional array, like so:
"field_name": [
"",
"option 6",
"option 11",
""
]
(btw I have no idea why all these fields produce those blank values, but that's a matter for another day)
I am trying to make an interface on the front end where you can select one or more of these values and the result will come back if ANY of them are found for that record. Think of it like a tag list, if the item has just one of the values it should be returned.
I can use the [contains] operator to find if it has one of the values I'm looking for, but I can only pass a single value, whereas I need all that have either optionX OR optionY OR optionZ. I would basically need a combination of [contains] and [in] to achieve what I'm trying to do. Is there a way to achieve this?
I've also tried setting the [logical] operator to OR, but then that screws up the other filters that need to be included as AND (or I'm doing something wrong). Not to mention the query gets completely unruly.
Help?

Sort a list of custom objects multiple times by different object properties in vb.net

I want to sort a list of custom objects by multiple object properties.
For example, I have:
MyObject.A
MyObject.B
MyObject.C
I want to sort the list first by the values of property "A", then by B and then by C. All those properties are strings(that may or may not be equal to each other and may or may not consist of/contain number characters).
After digging through web I found something that worked for the case where I only needed to sort the list by one property (by "A" in this example):
MyList.Sort(Function(x, y) x.A.CompareTo(y.A))
That worked fine.
So after that, I figured I just need to do more sorts in correct order and I tried doing something like this:
MyList.Sort(Function(x, y) x.C.CompareTo(y.C))
MyList.Sort(Function(x, y) x.B.CompareTo(y.B))
MyList.Sort(Function(x, y) x.A.CompareTo(y.A))
Which kinda sometimes works and sometimes doesn't. If there are few list entries (<10), it works fine and, for example, if "A" values are equal, the list is sorted by "B" values and if those are equal, then by "C".
But, when I add more entries, it breaks down and only the last sort is correct.
Seems that each next sort doesn't retain the original order of entries it doesn't need to sort.
How would I sort something like this?
MyList = (MyList.OrderBy(Function(i) i.A).
ThenBy(Function(i) i.B).
ThenBy(Function(i) i.C)).ToList()
As to why your existing method did not work: that's the difference between a stable and an unstable sort. According to MSDN, the Sort() method unstable.