In my code, i have switch case such as
switch(iSortCol) {
case1: if(iSortDir="desc"){order1 = order1.OrderByDescending(x=>x.GROUPNAME);
elseif(iSortDir="asc")order1 = order1.OrderBy (x=>x.GROUPNAME);
case2: if(iSortDir="desc"){order1 = order1.OrderByDescending(x=>x.GROUPMASTERID);
elseif(iSortDir="asc")order1 = order1.OrderBy (x=>x.GROUPMASTERID);}
....
case80:
case81:
}
The growing of "switch...case..." leads more maintain work for the code, i am thinking how to covert the code to Dictionary or strategy pattern for a better maintainability.
By the way, the property in order 1 such as "GROUPNAME","GROUPMASTERID" has different type
E.g. the "GROUPNAME" in (x=>x.GROUPNAME) is string type, but the "GROUPMASTERID" in (x=>x.GROUPMASTERID) int type.
Could anyone give me some clues, really appreciated
Related
I'm new to Lua (like, yesterday new), so please bear with me...
I apologize for the convoluted nature of this question, but I had no better idea of how to demonstrate what I'm trying to do:
I have a Lua table being used as a dictionary. The tuples(?) are not numerically indexed, but use mostly string indices. Many of the indices actually relate to sub-tables that contain more detailed information, and some of the indices in those tables relate to still more tables - some of them three or four "levels" deep.
I need to make a function that can search for a specific item description from several "levels" into the dictionary's structure, without knowing ahead of time which keys/sub-keys/sub-sub-keys led me to it. I have tried to do this using variables and for loops, but have run into a problem where two keys in a row are being dynamically tested using these variables.
In the example below, I'm trying to get at the value:
myWarehouselist.Warehouse_North.departments.department_one["rjXO./SS"].item_description
But since I don't know ahead of time that I'm looking in "Warehouse_North", or in "department_one", I run through these alternatives using variables, searching for the specific Item ID "rjXO./SS", and so the reference to that value ends up looking like this:
myWarehouseList[warehouse_key].departments[department_key][myItemID]...?
Basically, the problem I'm having is when I need to put two variables back-to-back in the reference chain of a value being stored at level N of a dictionary. I can't seem to write it out as [x][y], or as [x[y]], or as [x.y] or as [x].[y]... I understand that in Lua, x.y is not the same as x[y] (the former directly references a key by string index "y", while the latter uses the value being stored in variable "y", which could be anything.)
I've tried many different ways and only gotten errors.
What's interesting is that if I use the exact same approach, but add an additional "level" to the dictionary with a constant value, such as ["items"] (under each specific department), it allows me to reference the value without issue, and my script runs fine...
myWarehouseList[warehouse_key].departments[department_key].items[item_key].item_description
Is this how Lua syntax is supposed to look? I've changed the table structure to include that extra layer of "items" under each department, but it seems redundant and unnecessary. Is there a syntactical change that I can make to allow me to use two variables back-to-back in a Lua table value reference chain?
Thanks in advance for any help!
myWarehouseList = {
["Warehouse_North"] = {
["description"] = "The northern warehouse"
,["departments"] = {
["department_one"] = {
["rjXO./SS"] = {
["item_description"] = "A description of item 'rjXO./SS'"
}
}
}
}
,["Warehouse_South"] = {
["description"] = "The southern warehouse"
,["departments"] = {
["department_one"] = {
["rjXO./SX"] = {
["item_description"] = "A description of item 'rjXO./SX'"
}
}
}
}
}
function get_item_description(item_id)
myItemID = item_id
for warehouse_key, warehouse_value in pairs(myWarehouseList) do
for department_key, department_value in pairs(myWarehouseList[warehouse_key].departments) do
for item_key, item_value in pairs(myWarehouseList[warehouse_key].departments[department_key]) do
if item_key == myItemID
then
print(myWarehouseList[warehouse_key].departments[department_key]...?)
-- [department_key[item_key]].item_description?
-- If I had another level above "department_X", with a constant key, I could do it like this:
-- print(
-- "\n\t" .. "Item ID " .. item_key .. " was found in warehouse '" .. warehouse_key .. "'" ..
-- "\n\t" .. "In the department: '" .. dapartment_key .. "'" ..
-- "\n\t" .. "With the description: '" .. myWarehouseList[warehouse_key].departments[department_key].items[item_key].item_description .. "'")
-- but without that extra, constant "level", I can't figure it out :)
else
end
end
end
end
end
If you make full use of your looping variables, you don't need those long index chains. You appear to be relying only on the key variables, but it's actually the value variables that have most of the information you need:
function get_item_description(item_id)
for warehouse_key, warehouse_value in pairs(myWarehouseList) do
for department_key, department_value in pairs(warehouse_value.departments) do
for item_key, item_value in pairs(department_value) do
if item_key == item_id then
print(warehouse_key, department_key, item_value.item_description)
end
end
end
end
end
get_item_description'rjXO./SS'
get_item_description'rjXO./SX'
I want to delete the part of string existing after "|". For Example String s = HelloWorld|ABCD i want to delete ABCD.
I want to do it in asp.net. Help Will be much appreciated.
subString method might be used for this but i dont know how to do it.
Kindly help me out with this.
int pipeIndex = s.IndexOf("|");
s = pipeIndex == - 1 ? s : s.Substring(0, pipeIndex);
This is the most efficient way, maybe you find this more readable:
s = s.Split('|')[0];
I'm currently having troubles figuring out how to use Java 8 streams.
I'm trying to go from lista_dottori (Map<Integer, Doctor>) to a new map patientsPerSp where to every medical specialization (method getSpecialization) I map the number of patients wich have a doctor with this specialization (method getPatients in class Doctor returns a List of that doctor's patients). I can't understand how to use the counting method for this purpose, and I can't seem to find any examples nor explanations for this kind of problems on the internet.
That's what i've written, it does give me error in the counting section:
public Collection<String> countPatientsPerSpecialization(){
patientsPerSp=
lista_dottori.values().stream()
.map(Doctor::getSpecialization)
.collect(groupingBy(Doctor::getSpecialization, counting(Doctor::getPatients.size())))
;
}
Seems that you want to sum the sizes of patients lists. This can be done by summingInt() collector, not counting() (which just counts occurences; doctors in this case). Also mapping seems to be unnecessary here. So you cuold write:
patientsPerSp = lista_dottori.values().stream()
.collect(groupingBy(Doctor::getSpecialization,
summingInt(doctor -> doctor.getPatients().size())));
Note that the results will be incorrect if several doctors have the same patient (this way it will be counted several times). If it's possible in your case, then it would be probably better to make a set of patients:
patientsPerSp = lista_dottori.values().stream()
.collect(groupingBy(Doctor::getSpecialization,
mapping(Doctor::getPatients(), toSet())));
This way you will have a map which maps specialization to the set of patients, so the size of this set will be the count which you want. If you just need the count without set, you can add a final step via collectingAndThen():
patientsPerSp = lista_dottori.values().stream()
.collect(groupingBy(Doctor::getSpecialization,
collectingAndThen(
mapping(Doctor::getPatients(), toSet()),
Set::size)));
I solved the problem avoiding using the streams. That's the solution I used:
public Collection<String> countPatientsPerSpecialization(){
int numSpec = 0;
Map<String, Integer> spec = new HashMap<>();
for(Doctor d : lista_dottori.values()){
if(!spec.containsKey(d.getSpecialization())){
spec.put(d.getSpecialization(), d.getPatients().size());
numSpec++;
}
else{ //cioè se la specializzazione c'è già
spec.replace(d.getSpecialization(), +d.getPatients().size());
}
}
patientsPerSp.add(spec.keySet() + ": " + spec.values());
for(String s : patientsPerSp)
System.out.println(s);
return patientsPerSp;
}
I couldn't seem to be able to solve it using your solutions, although they were very well exposed, sorry.
Thank you anyway for taking the time to answer
Map<String, Integer> patientsPerSpecialization =
doctors.values()
.stream()
.collect(Collectors.groupingBy(Doctor::getSpecialization,
Collectors.summingInt(Doctor::nberOfAssignedPatients)));
I have a code someone wrote and there
this->llBankCode = new widgetLineEditWithLabel(tr("Bankleitzahl"), "", Qt::AlignTop, this);
QRegExpValidator *validatorBLZ = new QRegExpValidator(this);
validatorBLZ->setRegExp(QRegExp( "[0-9]*", Qt::CaseSensitive));
this->llBankCode->lineEdit->setValidator(validatorBLZ);
as it can be seen from this code, is that validatorBLZ can accept only numbers between 0 and 9. I would like to change it, that validatorBLZ would be able to get as an input whitespace as well (but not to start with a whitespace), but it wont be shown.
Example:
if i try to copy & paste a string of the format '22 34 44', the result would be an empty field. What i would like to happen is that the string '22 34 44' will be shown in the field as '223444'.
How could i do it?
You could try using:
QString string = "22 34 44";
string.replace(QString(" "), QString(""));
That will replace any spaces with a non-space.
Write your own QValidator subclass and reimplement validate and fixup. Fixup does what you ask for: changes the input in a way that makes it intermediate/acceptable.
In your case, consider the following code-snippet for fixup:
fixup (QString &input) const
{
QString fixed;
fixed.reserve(input.size());
for (int i=0; i<input.size(); ++i)
if (input.at(i).isDigit()) fixed.append(input.at(i));
input = fixed;
}
(this is not tested)
The validate function will obviously look similar, returning QValidator::Invalid when it encounters a non-digit character and returning the according position in pos.
If your BLZ is limited to Germany, you could easily add the validation feature that it only returns QValidator::Acceptable when there are eight digits, and QValidator::Intermediate else.
Anyhow, writing an own QValidator, which often is very easy and straight forward, is the best (and most future-proof) solution most of the time. RegExes are great, but C++ clearly is the more powerful language here, which in addition results in a much more readable validator ;).
We're looking into refining our User Groups in Dynamics AX 2009 into more precise and fine-tuned groupings due to the wide range of variability between specific people within the same department. With this plan, it wouldn't be uncommon for majority of our users to fall user 5+ user groups.
Part of this would involve us expanding the default length of the User Group ID from 10 to 40 (as per Best Practice for naming conventions) since 10 characters don't give us enough room to adequately name each group as we would like (again, based on Best Practice Naming Conventions).
We have found that the main information seems to be obtained from the UserGroupInfo table, but that table isn't present under the Data Dictionary (it's under the System Documentation, so unavailable to be changed that way by my understanding). We've also found the UserGroupName EDT, but that is already set at 40 characters. The form itself doesn't seem to restricting the length of the field either. We've discussed changing the field on the SQL directly, but again my understanding is that if we do a full synchronization it would overwrite this change.
Where can we go to change this particular setting, or is it possible to change?
The size of the user group id is defined as as system extended data type (here \System Documentation\Types\userGroupId) and you cannot change any of the properties including the size 10 length.
You should live with that, don't try to fake the system using direct SQL changes. Even if you did that, AX would still believe that length is 10.
You could change the SysUserInfo form to show the group name only. The groupId might as well be assigned by a number sequence in your context.
I wrote a job to change the string size via X++ and it works for EDTs, but it can't seem to find the "userGroupId". From the general feel of AX I get, I'd be willing to guess that they just have it in a different location, but maybe not. I wonder if this could be tweaked to work:
static void Job9(Args _args)
{
#AOT
TreeNode treeNode;
Struct propertiesExt;
Map mapNewPropertyValues;
void setTreeNodePropertyExt(
Struct _propertiesExt,
Map _newProperties
)
{
Counter propertiesCount;
Array propertyInfoArray;
Struct propertyInfo;
str propertyValue;
int i;
;
_newProperties.insert('IsDefault', '0');
propertiesCount = _propertiesExt.value('Entries');
propertyInfoArray = _propertiesExt.value('PropertyInfo');
for (i = 1; i <= propertiesCount; i++)
{
propertyInfo = propertyInfoArray.value(i);
if (_newProperties.exists(propertyInfo.value('Name')))
{
propertyValue = _newProperties.lookup(propertyInfo.value('Name'));
propertyInfo.value('Value', propertyValue);
}
}
}
;
treeNode = TreeNode::findNode(#ExtendedDataTypesPath);
// This doesn't seem to be able to find the system type
//treeNode = treeNode.AOTfindChild('userGroupId');
treeNode = treeNode.AOTfindChild('AccountCategory');
propertiesExt = treeNode.AOTgetPropertiesExt();
mapNewPropertyValues = new Map(Types::String, Types::String);
mapNewPropertyValues.insert('StringSize', '30');
setTreeNodePropertyExt(propertiesExt, mapNewPropertyValues);
treeNode.AOTsetPropertiesExt(propertiesExt);
treeNode.AOTsave();
info("Done");
}