Tufan Chand
Tufan Chand

Reputation: 752

Update the property of list items without "loop" and "if"

I am updating the property of the list items.

class Response
{
    public string Name { get; set; }
    public int Order { get; set; }
}

Here I want to update the Order of a List<Response> variable. As of now, I am looping through each item of the list and updating it.

List<Response> data = FromDb();
foreach (var item in data)
{
    if(item.Name.Equals("A"))
    {
       item.Order=1;
    }
    if(item.Name.Equals("B"))
    {
       item.Order=2;
    }
    //Like this I have arround 20 conditions
}

The above code is working fine, but the problem is the Cognitive Complexity of the method is more than the allowed.

I tried something like below

data.FirstOrDefault(x => x..Equals("A")).Order = 1;
data.FirstOrDefault(x => x..Equals("B")).Order = 2;
//and more ...

In this code also null check is not in place, So if the searching string is not present in the list then again it will break.

If I add null check condition then again the complexity getting higher.

So here I want without any for loop or if, If I can update the Order of the list by using linq/lamda or anything else.

Upvotes: 0

Views: 2123

Answers (1)

asgerhallas
asgerhallas

Reputation: 17714

I don't know how you measure Cognitive Complexity and how much of it is allowed to be pushed out into other functions, but something like this makes the ordering quite declarative?

[Fact]
public void TestIt()
{
    var data = FromDb().Select(SetOrder(
        ("A", 1),
        ("B", 2)
    ));
}

static Func<Response, Response> SetOrder(params (string Name, int Order)[] orders)
{
    var orderByKey = orders.ToDictionary(x => x.Name);

    return response =>
    {
        if (orderByKey.TryGetValue(response.Name, out var result))
            response.Order = result.Order;

        return response;
    };
}

Addendum in response to comment:

In order to have a default value for unmatched names, the SetOrder could be changed to this:

static Func<Response, Response> SetOrder(params (string Name, int Order)[] orders)
{
    var orderByKey = orders.ToDictionary(x => x.Name);

    return response =>
    {
        response.Order = 
            orderByKey.TryGetValue(response.Name, out var result)
                ? result.Order
                : int.MaxValue;

        return response;
    };
}

Upvotes: 3

Related Questions