String i;
String j;
String k;
i.concat(j).concat(k);
Now I want to write this in DRL file.
rule "X"
when
xx : X(i.concat(j).concat(k))
I am new with Drools, please help me to build the string inside the when condition in DRL file.
I can't think of any good reason to want to do this. The "when" clause is for checking conditions (broadly equivalent to an "if" statement.)
Now, assuming you have some input object X that looks like this:
class X {
String i;
String j;
String k;
}
... you can create a String that's the concatenated form of the i, j and k values in a few ways.
One way would be like this:
rule "Str from x - v1"
when
X( $i: i, $j: j, $k: k )
$str: String() from $i.concat($j).concat($k)
then
// do something with $str
end
If you're just trying to compare to the concatenated value, you could just, you know, concatenate the fields at the time of comparison instead of assigning them to a variable:
rule "Just compare it"
when
X( $i: i, $j: j, $k: k )
SomethingElse( myStr == $i + $j + $k )
then
// ...
end
Since $i, $j, and $k values are immutable (since they're Strings), you can concatenate them at any time and always get the same result, so it's not even a case of "the values might change from under me". So while there's very little reason to ever do this, here's how you'd go about it.
Related
I am looking for a way to set up the fprintf function so that it returns the string 1->2->...->n for any input n. However, I cannot find a way to do so without having an extra arrow attached at the beginning (->1->2->...->n) or the end of the string (1->2->...->n->). Is there a way around this?
You could use strjoin for this...
n = 4;
str = strjoin( arrayfun(#num2str, 1:n, 'uni', 0), '->' );
% str = '1->2->3->4'
Or if you're set on using fprintf (or sprintf), you could manually add the first element (for ease, assume n >= 1)
str = ['1', sprintf('->%.0f', 2:n )];
If you just want to print these to the Command Window, simply use disp on either option instead of (or after) assigning to str. If you're writing to a file with fprintf then simply use fprintf( fid, [str '\n'] ) to print the line to file.
For this type of task, the solution is to print either the first or the last element separately:
n = 8;
fprintf('%d', 1);
fprintf('->%d', 2:n);
fprintf('\n');
Here's another approach to build the desired string:
n = 10;
str = regexprep(num2str(1:n), '\s+', '->');
This gives
str =
'1->2->3->4->5->6->7->8->9->10'
I would like to perform an iteration over an array of objects. Instead of writing
for item in items
for k, v in item
# Do Something
I would like to do something similar to this
for k,v of item in items
# Do something
Which based on the compiled output is not supported:
var k, ref, ref1, v, indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
ref1 = (ref = indexOf.call(items, item) >= 0) != null ? ref : [];
for (k in ref1) {
v = ref1[k];
# Do something
}
Is there any other comprehension-like operation through which I can perform this shortcut?
EDIT: I can refer to specific keys in the object by doing
for { k1, k2 }, i in items
# Do something
For the sake of the question, assume the keys are dynamic
No you can't. Following coffeescript's golden rule “it's just JavaScript”, consider looking at the source where a for loop gets translated. You will need two Javascript fors and you only can get one from a coffescript for (the for gets inserted in line 2079).
The javascript result you want to have is something like this:
for(_i…;…;…){
var _x = items[_i];
for(k in _x){
var v = _x[k]
…
}}
There are only two ways to get a javascript for loop (apart from the prewritten ones, like in class definitions): On “Range compilation”, which always gives a for(…;…;…) loop (which contructs an array inside a closure that will be returned) and for the for construct.
Your example to access single keys works because you are using some very special case of destructuring assignment. What you would need is a destructuring that extracts key-value pairs and there is none. If you look at the compiled example constructs like this get translated into a=items[i].a so such that there is no iteration. You even can omit the ,i:
for {a} in items
#iterate over the .a values of items
If your #Do something is just one line, you can put your fors on one line, but I personally think it doesn't increase the readability.
console.log [k,v] for k,v of i for i in items
Say I typed x = 'BODD' into the command prompt of MATLAB and then said x(1) it would return B. What I want is x(1) to return the empty String ('') or nothing etc. and x(2) to return B and so forth up until x(5) returning the final D?
I assume that you mean that you really do want the empty zero-length string, ''. There have been some Answers to this question that assume that you meant that you wanted the one-character string that contains a space, ASCII value 32.
If that's the case, I'm afraid you can't to that - MATLAB arrays (including character arrays, which is all that a MATLAB "string" is) don't work that way. There are two ways to look at it...
You asked for x(1). Now, the indexing expression that you used, 1, has size 1x1. Therefore, you are guaranteed to get either a 1x1 return value, OR an error. That means that there's no way to get a 0x1 or 0x0 (the true "empty string"). This is similar to the way that, if you had asked for x(2:4), you would be guaranteed to get a 1x3 array of characters back. In that case, 2:4 is a 1x3 array.
There's no way to "meaningfully" prepend a zero-length string to the beginning of another string. If a = 'WXYZ';, then running b = ['' a] just returns 'WXYZ' back. It didn't somehow stick a magical placeholder for an empty string at the front of the original string.
You can't concatenate '' at end or beginning
However, you can have blank/space, like this :-
>> x=BODD;
>> x=[' ' x]; % Use normal matrix concatenation
>> x(1)
ans =
>> x(2)
ans =
B
Try following concatenation
x = [' ' x];
If you want the string itself to still be 'BODD', you could try writing a custom function:
function [char] = emptyConcat(string, index)
if (index == 1)
char = '';
else
char = string(index - 1);
I am trying to assign valuable, which is number and given by for loop, to the name of structure field. For example, I would like to do as following,
A.bx, where A is name of structure(= char), b is part of field name ( = char) and x is valuable given by for loop. A and b is fixed or predefined.
Any comment is appreciated !
genvarname(str,list) generates a valid variable name in str [a string] in which at each iteration value in str is different from the exclusion list
And fieldname(S) returns a list of all the names of the field already in the structure S (use it to create a exclusion list)
Here is a code for what you want:
A = struct ();
for i = 1:5
A.(genvarname ('b', fieldnames (A))) = i;
end
Read about 1. genvarname(str,list) 2. fieldnames(S)
You can name you struct fields using simple sprintf
A = struct()
for ii = 1:10
fn = sprintf('b%d', ii );
A.(fn) = ii; % use the struct
end
I tend to agree with sebastian that suggested using arrays or cells over this type of field naming. In addition to cells and arrays you might find containers.Map to be very versatile and useful.
Suppose I have a function that is something like this:
function [ c ] = input_args(m)
for i = 1 : m+1
c{i} = inputdlg('Enter next m value');
end
end
Now I'd like to change this so that the instruction to the user at the i'th stage of the for loop says something like "Enter the i'th m value", where i is the changing index in the for loop. How can I do this?
Thanks!
A string is a array of characters, so you can concatenate them like any other array. You need to use num2str to convert a number into a printable character.
inputdlg(['Enter the ' num2str(i) 'th m value']);
A more general solution would be to use sprintf to format your string; to do the same thing with sprintf you would use:
inputdlg(sprintf('Enter the %dth m value', i));
which you might find more readable (and allows you to use standard fprintf formatting options).