Search arrays for values I implemented a search function like this:

private static void GetResults(ref ObservableCollection&lt;string&gt; resultTitles, ref string[] query, ref ObservableCollection&lt;int&gt; weight)
{
    int position = -1;

    foreach (string[] r in SearchKeys.Keys)
    {
        position++;
        foreach (string s in query)
        {
            int m = r.Length/2;
            int min = r[m][0] &lt; s[0] ? m : 0;
            int max = r[m][0] &lt;= s[0] ? r.Length : m+1;

            for (int i = min; i &lt; max; i++)
            {
                weight.Add(0);

                if (r[i] == s)
                {
                    if (weight[position] == 0)
                    {
                        resultTitles.Add(r[0]);
                    }
                    weight[position]++;

                }   // end if
            }   // end foreach(s)
        }   // end foreach(t)
    }   // end foreach(r)
}


In the main program, the use inputs a query, the program splits the query at the spaces, and passes the query and two empty ObservableCollections to this function.

SearchKeys.Keys is implemented like this:

public static string[][] Keys = { Array1, Array2, Array3 };


The arrays are implemented like this:

private static string[] Array1 = { "Title", "val1", "val2", "val3", "val4", "val5", "val6" };


As always, all comments are welcome; particularly, I am interested in which ways could this code's performance be improved.  The data in SearchKeys is sorted, of course.

This is a previous version of my code, which may also be of interest.  This version should run about twice as slow as the above, according to my estimates:

private void getResults(ref ObservableCollection&lt;string&gt; tmp, ref string[] query, ref ObservableCollection&lt;int&gt; weight)
{
    int position = -1;

    foreach (string[] r in SearchKeys.Keys)
    {
        position++;
        foreach (string t in r)
        {
            weight.Add(0);

            foreach (string s in query)
            {
                if (t == s)
                {
                    if (weight[position] == 0)
                    {
                        tmp.Add(r[0]);
                    }
                    weight[position]++;

                }   // end if
            }   // end foreach(s)
        }   // end foreach(t)
    }   // end foreach(r)
}


This is how I call this function:

static void Main(string[] args)
{
    ObservableCollection&lt;int&gt; weight = new ObservableCollection&lt;int&gt;();
    ObservableCollection&lt;string&gt; resultTitles = new ObservableCollection&lt;string&gt;();
    string[] query = Console.ReadLine().Split(' ');

    GetResults(ref resultTitles, ref query, ref weight);
    StableSort(ref resultTitles, ref weight);

    foreach (string s in resultTitles)
        Console.WriteLine(resultTitles.IndexOf(s)+": "+s);
}


This is StableSort (see Stable Sort in C#):

static void StableSort(ref ObservableCollection&lt;string&gt; values, ref ObservableCollection&lt;int&gt; weights)
{
    while(weights.Contains(0))
    {
        weights.Remove(0);
    }

    if (values == null) { throw new ArgumentNullException("values"); }
    if (weights == null) { throw new ArgumentNullException("weights"); }

    if (values.Count != weights.Count) { throw new ArgumentOutOfRangeException("collections count not equal", (Exception)null); }

    ObservableCollection&lt;string&gt; localValues = new ObservableCollection&lt;string&gt;();
    ObservableCollection&lt;int&gt; localWeights = new ObservableCollection&lt;int&gt;();

    int index = -1;
    var weightsWithIndex = weights.Select(p =&gt; new { Value = p, Index = ++index }).OrderByDescending(p =&gt; p.Value);

    foreach (var w in weightsWithIndex)
    {
        localWeights.Add(w.Value);
        localValues.Add(values[w.Index]);
    }

    values = localValues;
    weights = localWeights;
}
You're doing a good job at indenting your code, well done! But then why would you need these?


            }   // end if
        }   // end foreach(s)
    }   // end foreach(t)
}   // end foreach(r)



Now, the signature:


private static void GetResults(ref ObservableCollection&lt;string&gt; resultTitles, ref string[] query, ref ObservableCollection&lt;int&gt; weight)



"void GetResults"... "void Get". And then the two ref parameters...


  and passes the query and two empty ObservableCollections to this function.


query doesn't need to be passed by reference, doesn't need to be specifically an array, and if I had to use ref parameters I'd put it first in the signature:

private static void GetResults(IEnumerable&lt;string&gt; query, ref ObservableCollection&lt;string&gt; resultTitles, ref ObservableCollection&lt;int&gt; weight)


Now, the method doesn't care that our collections are observable - it only needs to know it's some kind of ICollection&lt;T&gt;... but there's a smell there nonetheless: passing ref parameters instead of returning a collection, doesn't feel quite natural.

I believe, because it's a private method, that whatever you're passing in as weight could be promoted to a private field if it's used anywhere else in the class, or moved to the GetResults scope where it's used.