I have code that looks something like this. An 'if else' chain with each one containing a long list of conditions of when that function should get called.
if (conditionA1() || conditionA2() && conditionA3() || ... && conditionAN()) {
functionA();
}
else if (conditionB1() || conditionB2() && conditionB3() || ... && conditionBN() {
functionB();
}
...
else if (conditionZ1() || conditionZ2() && conditionZ3() || ... && conditionZN()) {
functionZ();
}
It looks like messy code which could get hard to maintain and was wondering if there is a good design pattern to refactor this.
I know two good tricks for dealing with long chains of conditionals.
The first is to create named variables to describe the combined conditions.
firstCompoundCondition = conditionA1() || conditionA2() && conditionA3() || ... && conditionAN();
secondCompoundCondition = conditionB1() || conditionB2() && conditionB3() || ... && conditionBN();
...
nthCompoundCondition = conditionZ1() || conditionZ2() && conditionZ3() || ... && conditionZN();
if (firstCompoundCondition) {
functionA();
}
else if (secondCompoundCondition) {
functionB();
}
...
else if (nthCompoundCondition) {
functionZ();
}
The second - and this is kind of subtle and perhaps ultimately more powerful - is to eliminate the need for all the elses by structuring your code to return, ideally returning the result of the inner function, but simply returning inside the block can work as well. This can mean extracting a function which doesn't look like much, but when all is said and done it's a lot cleaner.
firstCompoundCondition = conditionA1() || conditionA2() && conditionA3() || ... && conditionAN();
secondCompoundCondition = conditionB1() || conditionB2() && conditionB3() || ... && conditionBN();
...
nthCompoundCondition = conditionZ1() || conditionZ2() && conditionZ3() || ... && conditionZN();
if (firstCompoundCondition) return functionA();
if (secondCompoundCondition) return functionB();
...
if (nthCompoundCondition) return functionZ();
If the conditions are all different, then nesting wouldn't be possible...however, what I find sometimes more readable is if I put each condition (or every two conditions) on a separate line, such as:
if (conditionA1() ||
conditionA2() && conditionA3() ||
... &&
conditionAN()) {
functionA();
}
else if (conditionB1() ||
conditionB2() && conditionB3() ||
... &&
conditionBN() {
functionB();
}
...
else if (conditionZ1() ||
conditionZ2() && conditionZ3() ||
... && conditionZN()) {
functionZ();
}
It looks kind of funny here, but usually if I do it with actual conditionals it looks better :)
Related
I have the following function that works fine until I try to update the gender or age fields
since there is a check against the src doc that is causing the failure how to go about it in a way that will allow updates to other fileds ?, without erroring out when there is no (count) in the incoming update ?
batch.update(doc(db, 'docPath', { gender: selected.gender });
function dataCheckUpdate(requestData, resourceData) {
return (
// gender
requestData.gender is string &&
// age
requestData.age is number &&
// count
requestData.count is number &&
requestData.count == resourceData.count + 1 &&
// (!('count' in requestData.keys()) || (requestData.count == resourceData.count + 1)) &&
requestData.count <= 2 &&
);
}
// call
dataCheckUpdate(request.resource.data, resource.data)
I want to implement this functionality but vendBalanceProvisionalTmpProcesing is always empty, i know it is empty because it is tempDB :
while select AccountNum,PostingProfile from vendProvisionalBalanceTmpProcessing
{
select sum(AmountCur) from vendTrans
where vendTrans.AccountNum == vendProvisionalBalanceTmpProcessing.AccountNum
&& vendTrans.PostingProfile == vendProvisionalBalanceTmpProcessing.PostingProfile
&& vendTrans.TransDate >= _fromDate
&& vendTrans.TransDate <= toDate;
tempSum += vendTrans.AmountCur;
select sum(AmountMST) from vendTrans
where vendTrans.AccountNum == vendProvisionalBalanceTmpProcessing.AccountNum
&& vendTrans.PostingProfile == vendProvisionalBalanceTmpProcessing.PostingProfile
&& vendTrans.TransDate >= _fromDate
&& vendTrans.TransDate <=toDate;
tempSum+= vendTrans.AmountMST*ledgerParameters.EonExchangeRate;
tmpValue.Amount = tempSum;
tmpValue.AccountNum = vendTrans.AccountNum;
tmpValue.PostingProfile = vendTrans.PostingProfile;
tmpValue.doInsert();
}
But there are 2 scenarios where i can access to vendProvisionalBalanceTmpProcessing.AccountNum :
insert_recordset tmpValue
(AccountNum, PostingProfile, Amount)
select AccountNum
from vendProvisionalBalanceTmpProcessing
group by AccountNum
join PostingProfile, sum(AmountMST) from vendTrans
group by PostingProfile
where vendTrans.AccountNum == vendProvisionalBalanceTmpProcessing.AccountNum
&& vendTrans.PostingProfile == vendProvisionalBalanceTmpProcessing.PostingProfile
&& vendTrans.TransDate < _fromDate;
update_recordset vendProvisionalBalanceTmpProcessing
setting OpeningBalance = tmpValue.Amount
join tmpValue
where tmpValue.AccountNum == vendProvisionalBalanceTmpProcessing.AccountNum
&& tmpValue.PostingProfile == vendProvisionalBalanceTmpProcessing.PostingProfile;
Any way how i can do while select like that ?
`
I need vendProvisionalBalanceTmpProcessing.AccountNum to do two select sum over vendTrans where vendTrans.AccountNum == vendProvisionalBalanceTmpProcessing.AccountNum. So way how to do it similar to these two scenarios where i have access to vendProvisionalBalanceTmpProcessing would help me.
You would like to reread on how to link to a temporary table. Official documentation.
Especially, to access a tempDB table from outside where it is created, you need to call linkPhysicalTableInstance.
I do not need to know the actual results or even a count - just if the result is null or not.
I am currently doing it like this and then looking at the count:
int itemsNeedingUpdated =
(from i in cDb.DistributionLineItems
where (i.CompanyNo == item.dt_company_no && i.UniqueIdNo == item.Unique_Id_No) &&
(i.DatetimeUpdated >= startingDateTimeToSearch) &&
(i.ReceivingScanPieces > 0 || i.LoadingScanPieces > 0 || i.ActualPieces > 0)
select i.UniqueIdNo).Count();
but as this is going to churn through a lot of times I want to know if this is the fastest way to check this?
Using EF 6 against Azure SQL.
You can use Any:
bool itemsNeedingUpdated =
(from i in cDb.DistributionLineItems
where (i.CompanyNo == item.dt_company_no && i.UniqueIdNo == item.Unique_Id_No) &&
(i.DatetimeUpdated >= startingDateTimeToSearch) &&
(i.ReceivingScanPieces > 0 || i.LoadingScanPieces > 0 || i.ActualPieces > 0)
select i.UniqueIdNo).
Any();
Which will bail out as soon as an item matching the predicate is found.
When if condition is huge and take several lines then condition and body become a monoblock, because default indent is 4 and IDEA align multiline if to 4.
if (status != HttpStatus.OK.value()
|| doc.title().equals("Foo")
|| list.isEmpty()) {
logger.info("Awful readability.");
foobar();
ex.execute(this);
}
OR
if (status != HttpStatus.OK.value() ||
doc.title().equals("Foo") ||
list.isEmpty()) {
logger.info("The most horrible readability.");
foobar();
ex.execute(this);
}
Readability become so-so. For this I want insert a blank line after condition or insert additional indent for conditions by autoformat.
if (status != HttpStatus.OK.value()
|| doc.title().equals("Foo")
|| list.isEmpty()) {
logger.info("Good readability.");
foobar();
ex.execute(this);
}
OR
if (status != HttpStatus.OK.value()
|| doc.title().equals("Foo")
|| list.isEmpty()) {
logger.info("Good readability.");
foobar();
ex.execute(this);
}
Unfortunately, I can't find something in Code Style options.
IntelliJ IDEA code formatting does not have any support for automatically inserting blank lines in method bodies.
I am working on 3-tier Architecture project
and I have multiple DropDown Lists to make filtering of data that is fetched from database using LINQ.
Now I need a way to filter with these dropdowns where when I select an item in any dropdown it is filtering and when I select from two dropdowns to filter by these two selections and so on...
I use linq like this:
var doctors = from d in db.Doctors
where d.CityID == id
&& d.HasSecretary == hasSec
&& d.OldSystem == oldSys
&& d.MetDoctor == metDoc
&& d.PriceProblem == priceProb
&& d.EasyToConvince == easyToCon
&& d.ComputerSavvy == comSav
&& d.Sold == sold
&& d.NotInterested == notIntr
&& d.FollowUp == followUp
&& d.NewClinic == newClin
&& d.RequestedADemo == reqDemo
select d;
And it is filtering only when I select all dropdowns, and not individually.
Please help :)
You will have to do conditional where clauses e.g.
var doctors = from d in db.Doctors;
if (id != null)
doctors = doctors.Where(d => d.CityID == id);
if (hasSec)
doctors = doctors.Where(d => d.HasSecretary == hasSec);
// other if statements
// results
var results = doctors.ToList();