Mirth Traverse through a GlobalMap - mirth

In my mirth implementation (Mirth Connect Server 2.2.1) I have a GlobalMap that contains keys and properties comes from external property file. How do I get the key set from the Globalmap and iterate it to get the values?

You can iterate through the global map like so:
for each (key in globalMap.getVariables().keySet().toArray())
logger.info(key+': '+$g('key'));

I'm not sure exactly how you're initializing your key/value set, but here's a basic rundown of what I do.
To stick a key/value set in the GlobalMap:
//I will assume that you have your own routine for initializing the
//kv set from your property file
var kvPairs = {'key1':'value1',
'key2':'value2',
'key3':'value3'};
globalMap.put('keyValuePairs',kvPairs);
To extract the set from the GlobalMap:
// Method 1
// Grab directly from GlobalMap object.
var kvPairs = globalMap.get('keyValuePairs');
// Method 2
// Use the Mirth shorthand to search all map objects until the
// desired variable is located.
var kvPairs = $('keyValuePairs');
To iterate through the set:
// Method 1
// If you need to access both the keys and the associated values, then
// use a for in loop
for (var key in kvPairs)
{
var value = kvPairs[key];
// you now have key and value, and can use them as you see fit
}
// Method 2
// If you only need the values, and don't need the keys, then you can use
// the more familiar for each in loop
for each (var value in kvPairs)
{
// you now have value, and can use it as you see fit;
}

Related

How to write to an Element in a Set?

With arrays you can use a subscript to access Array Elements directly. You can read or write to them. With Sets I am not sure of a way to write its Elements.
For example, if I access a set element matching a condition I'm only able to read the element. It is passed by copy and I can't therefore write to the original.
For example:
columns.first(
where: {
$0.header.last == Character(String(i))
}
)?.cells.append(value: addValue)
// ERROR: Cannot use mutating member on immutable value: function call returns immutable value
You can't just change things inside a set, because of how a (hash) set works. Changing them would possibly change their hash value, making the set into an invalid state.
Therefore, you would have to take the thing you want to change out of the set, change it, then put it back.
if var thing = columns.first(
where: {
$0.header.last == Character(String(i))
}) {
columns.remove(thing)
thing.cells.append(value: addValue)
columns.insert(thing)
}
If the == operator on Column doesn't care about cells (i.e. adding cells to a column doesn't suddenly make two originally equal columns unequal and vice versa), then you could use update instead:
if var thing = columns.first(
where: {
$0.header.last == Character(String(i))
}) {
thing.cells.append(value: addValue)
columns.update(thing)
}
As you can see, it's quite a lot of work, so maybe sets aren't a suitable data structure to use in this situation. Have you considered using an array instead? :)
private var _columns: [Column]
public var columns : [Column] {
get { _columns }
set { _columns = Array(Set(newValue)) }
// or any other way to remove duplicate as described here: https://stackoverflow.com/questions/25738817/removing-duplicate-elements-from-an-array-in-swift
}
You are getting the error because columns might be a set of struct. So columns.first will give you an immutable value. If you were to use a class, you will get a mutable result from columns.first and your code will work as expected.
Otherwise, you will have to do as explained by #Sweeper in his answer.

How to assign method output to variable by reference MQL4

I'm guessing this question is going to apply to many similar languages other than MQL4 such as c++ (which I also forget how to use) which require you manually specify when you are passing by reference.
Method reference:
int[] previous = GetPrevious(i, ZigZagBuffer);
Method definition:
int GetPrevious[](int current, const double& buffer[])
{
int count = 0;
int result[];
// calculate count
ArrayResize(result,count);
// fill array
return result;
}
The resulting compile error is:
"Invalid Array Access"
From what I understand, this is because array's can only be passed by reference, but you have to explicitly state that you are passing it by reference. But the more I look up the syntax for passing by reference, the more I find articles about passing parameter by reference. (which I already know how to do as you can see in the code example.)
What is the syntax to assign the output of a method to a variable?
In case it matters, I only need to read the array multiple times; I'm not needing to alter or re-assign it after it is declared.
You cannot return array. You have to create it and pass into the function, fill inside the function and that's it.
OnTick(){
double array[]; //declaration of the array
fillArray(array,10); //passing array by ref, updating it there
Print(array[0]=0 && array[9]=9);//returns true
}
void fillArray(double &array[],int size){
ArrayResize(array,size);
for(int i=0;i<size;i++){array[i]=i;}
}

Specman: Is there a way to access different variables by some index?

in my verification environment I have 3 different registers with the same fields: load_0, load_1 and load_2.
Now I have the same function duplicated 3 times for every register and differs only in one line:
duplicated_func_0() {
value = timer_regs.load_0; //This is the only different line (in duplicated_func_1 - load_1 is substituted
...
};
Is there a better way to access variable name (that differs only by its index) than duplicate the same function 3 times?
Something like this:
not_duplicated_func(index : uint) {
value = timer_regs.load_%x; //Is there a way to put the input index in the variable name instead of %x?
};
I will appreciate any help you can provide.
Inside timer_regs I wouldn't define 3 variables, load_0, load_1 and load_2, but a list of the respective type:
extend TIMER_REGS vr_ad_reg_file {
loads[3] : list of TIMER_LOAD vr_ad_reg;
};
This way you can access each register by index.
If you can't change the layout you already have, just constrain each list item to be equal to your existing instances:
extend TIMER_REGS vr_ad_reg_file {
loads[3] : list of TIMER_LOAD vr_ad_reg;
keep loads[0] == load_0;
keep loads[1] == load_1;
keep loads[2] == load_2;
};

Is there a generic way of setting field values in mapper from list of values?

Is there a way of creating method for setting the value in the Model's fields without setting the values explicitly like -
ModelName.create.fieldName1("value").fieldName2("value2") and so on
Can we iterate through all available fields of that model and set their values form some list-of-values ?
something like ...
Model.allFields.foreach((fld)=> {
fld.set(valueList(indx)); indx+=1
}
Actually I want to set values into all models using some generic method that works for all models.
According to my comment:
val list = List(...)
val record = YourRecordClass.createRecord
record.allFields.zip(list).foreach {case(field,value) => field.setFromAny(value)}

How to update a property using Type.GetProperties() method?

I've a collection of a class' properties and would like to update each one's value by iterating over the collection through the index.
1) I create the collection of properties this way
private PropertyInfo[] GetPropertiesOfMyClass()
{
Type myType = (typeof(myClass));
PropertyInfo[] PropertyInfoArray = myType.GetProperties(
BindingFlags.Public |
BindingFlags.Instance);
return PropertyInfoArray;
}
2)Now, I'd like to set up the value of each one depending on the index this way
public void UpdateProperty(MyClass instanceOfMyClass, string valueToUpdate, int index)
{
//TODO:
//1. Get an individual property from the GetPropertyOfMyClass() using index
//2. Update the value of an individual property of the instanceOfMyClass
}
I'd like to be able to call UpdateProperty from a Controller like this:
UpdateProperty(instanceOfMyClass, valueToUpdate, indexOfTheProperty);
Honestly, I do not know how to involve the instanceOfMyClass in the game as GetProperty only plays with myClass.
Since I saw that I can use Name, PropertyType, ... to get information on the property. So, I've tried also GetPropertyOfMyClass()[index].SetValue(...), but I was lost in the arguments of its constructor, so I abandoned.
What I want is to be able to update the value of a property in my collection just by using the index.
Thanks for helping
Your guess was correct. You use SetValue() to update the value - this is how to do it:
GetPropertyOfMyClass()[index].SetValue( instanceOfMyClass, valueToUpdate, null);
The last argument can be null:
Optional index values for indexed properties. This value should be null for non-indexed properties.