HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpModerate

Returning a value based on a lookup

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
basedlookupreturningvalue

Problem

I am trying to return a value (a.tnAddress) from a custom class based on a lookup (foreach loop). Depending on the type of transaction, I will need to do the foreach loop based on different properties (sExecID, iMsgSeqNum, orsClOrderID). I prefer to not have 3 differentforeach` loops just but I am not sure how else to re-write this.

Keep in mind that the code is working fine; I just want to simplify it.

private TreeNode GetNodeAddress(cls_Transactions trPassedInTransaction)
{  
    switch (trPassedInTransaction.sMessageType)
    {
        case "Q":
        case "8b":
            foreach (cls_Transactions a in cls_GlobalVariables.transList)
            {
                if (trPassedInTransaction.sExecID == a.sExecID)
                {
                    return a.tnAddress;
                }
            }
            break;
        case "3":
            foreach (cls_Transactions a in cls_GlobalVariables.transList)
            {
                if (trPassedInTransaction.iMsgSeqNum == a.iMsgSeqNum)
                {
                    return a.tnAddress;
                }
            }
            break;
        default:
            foreach (cls_Transactions a in cls_GlobalVariables.transList)
            {
                if (trPassedInTransaction.sClOrderID == a.sClOrderID)
                {
                    return a.tnAddress;
                }
            }                    
            break;
    }

    return null;
}

Solution

This will add the use of LINQ to clean up the code the way you want:

private TreeNode GetNodeAddress(cls_Transactions trPassedInTransaction)
{
    //a predicate to pass to the FirstOrDefault method
    Func filter = null;
    switch (trPassedInTransaction.sMessageType)
    {

        case "Q":
        case "8b":
                 filter = x => trPassedInTransaction.sExecID == x.sExecID;
            break;
        case "3":
                 filter = x => trPassedInTransaction.iMsgSeqNum == x.iMsgSeqNum;
            break;
        default:
                 filter = x => trPassedInTransaction.sClOrderID == x.sClOrderID;                 
            break;
    }

    cls_Transactions result = cls_GlobalVariables.transList.FirstOrDefault(filter);
    return result != null ? result.tnAddress : null;
}


As an explanation, the switch statement has just been converted to use a predicate, which is a function type where it passes one parameter (in this case a cls_Transactions) and returns true/false.

The FirstOrDefault method is shorthand for the foreach loop and return, foreach-ing through the elements and using the predicate to determine if it meets the required condition, if none meet the required condition it will return a default value (in the case null).

You can use the First method also, which will throw an exception if nothing is found :)

Code Snippets

private TreeNode GetNodeAddress(cls_Transactions trPassedInTransaction)
{
    //a predicate to pass to the FirstOrDefault method
    Func<cls_Transactions,Boolean> filter = null;
    switch (trPassedInTransaction.sMessageType)
    {

        case "Q":
        case "8b":
                 filter = x => trPassedInTransaction.sExecID == x.sExecID;
            break;
        case "3":
                 filter = x => trPassedInTransaction.iMsgSeqNum == x.iMsgSeqNum;
            break;
        default:
                 filter = x => trPassedInTransaction.sClOrderID == x.sClOrderID;                 
            break;
    }

    cls_Transactions result = cls_GlobalVariables.transList.FirstOrDefault(filter);
    return result != null ? result.tnAddress : null;
}

Context

StackExchange Code Review Q#28622, answer score: 10

Revisions (0)

No revisions yet.