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

How can I refactor to avoid repetition finding the index of strings in a list?

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

Problem

I have a list of strings where I want to find the index of a first- and second-choice video compressor.

Logic: If the first choice is available, return its index. If not, and the second choice is available, return its index. If not, return zero.

Here is what I have now:

List availableVideoCompressors = GetAvailableVideoCompressors();
int compressorIndexToUse = 0;
if (availableVideoCompressors.Any(c => c.StartsWith("ffdshow", StringComparison.OrdinalIgnoreCase)))
    compressorIndexToUse = availableVideoCompressors.Select((c, i) => new { c, i }).First(c => c.c.Equals("ffdshow", StringComparison.OrdinalIgnoreCase)).i;
else if (availableVideoCompressors.Any(c => c.StartsWith("Microsoft Video 1", StringComparison.OrdinalIgnoreCase)))
    compressorIndexToUse = availableVideoCompressors.Select((c, i) => new {c, i}).First(c => c.c.StartsWith("Microsoft Video 1", StringComparison.OrdinalIgnoreCase)).i;
return compressorIndexToUse;


The problem is that I am iterating the list several times. Once to determine if the desired compressor is available, then again to obtain its index, for each candidate compressor.

I am not sure how to refactor to avoid this repetition. What can I do instead?

Solution

Let's start with a simpler problem where there's just one choice:

for (var i = 0; i < compressors.Count; i++)
{
    if (compressors[i].StartsWith(firstChoice, StringComparison.OrdinalIgnoreCase))
    {
        return i;
    }
}

return 0;


(I would much prefer returning -1 if no match is found, but requirements are requirements.)

Now we can build on top of this to deal with the second preference:

var secondChoiceIndex = -1;
for (var i = 0; i < compressors.Count; i++)
{
    if (compressors[i].StartsWith(firstChoice, StringComparison.OrdinalIgnoreCase))
    {
        return i;
    }

    if (secondChoiceIndex == -1 && compressors[i].StartsWith(secondChoice, StringComparison.OrdinalIgnoreCase))
    {
        secondChoiceIndex = i;
    }
}

return secondChoiceIndex == -1 ? 0 : secondChoiceIndex;

Code Snippets

for (var i = 0; i < compressors.Count; i++)
{
    if (compressors[i].StartsWith(firstChoice, StringComparison.OrdinalIgnoreCase))
    {
        return i;
    }
}

return 0;
var secondChoiceIndex = -1;
for (var i = 0; i < compressors.Count; i++)
{
    if (compressors[i].StartsWith(firstChoice, StringComparison.OrdinalIgnoreCase))
    {
        return i;
    }

    if (secondChoiceIndex == -1 && compressors[i].StartsWith(secondChoice, StringComparison.OrdinalIgnoreCase))
    {
        secondChoiceIndex = i;
    }
}

return secondChoiceIndex == -1 ? 0 : secondChoiceIndex;

Context

StackExchange Code Review Q#73378, answer score: 5

Revisions (0)

No revisions yet.