C# array question

Started by
8 comments, last by PM-Heavy 15 years, 8 months ago
I'm trying to add next/previous buttons for my C# program to cycle through files in a directory. I'm using Directory.GetFiles() to return a string[]. I'd like to start from the file that is already opened, and not from the beginning of the directory. I can find the filename of the opened file, but is there anyway to find where it is in the array? Sorry if this question is hard to understand, this is my first time working with file I/O. Also, to avoid making another thread I'll ask this question now: my next project will be a game and because I'd like to learn more C# it will probably use XNA. I'm wondering if Game Studio 3 is free? I know that the Express one is, but the download for 3 doesn't say anything about paying to download it, but it doesn't say it's an express edition either. Thanks for any help with either question.
Advertisement
Use this function to get the index of a value from an array:

        private int GetValueIndex(object[] array, object value)        {            for (int index = 0; index < array.Length; index++)            {                if (array[index] == value)                    return index;            }        }
Quote:Original post by Kuraitou
Use this function to get the index of a value from an array:

*** Source Snippet Removed ***


No need to reinvent the wheel: System.Array.IndexOf
Andre Loker | Personal blog on .NET
Or you could just use the provided Array.IndexOf method.

string[] myFiles;string myFileName;int index = Array.IndexOf(myFiles, myFileName);if (index == -1)    // not foundelse    // was found
Mike Popoloski | Journal | SlimDX
Thanks guys, Array.IndexOf is exactly what I was looking for.
Quote:Original post by PM-Heavy
Also, to avoid making another thread I'll ask this question now: my next project will be a game and because I'd like to learn more C# it will probably use XNA. I'm wondering if Game Studio 3 is free? I know that the Express one is, but the download for 3 doesn't say anything about paying to download it, but it doesn't say it's an express edition either.


There is only one XNA Game Studio (well, only one version per release, so there's only on XNA GS 2.0 and will only be one XNA GS 3.0). And it is free. "Express" was just attached to the first version because it only supported Visual C# 2005 Express. Now that XNA Game Studio works with all versions of Visual Studio, they've dropped the "Express" part of the name.
I'm not going to force my opinion, but I took the initiative to test the results between my loop method and Array.IndexOf.

(Using an array with 4096 elements) In 10,000 calls to either function, the loop took 0.188 seconds to execute, and the Array.IndexOf took 0.703 seconds. Similarly, with 50,000 calls, the loop took 0.937 seconds and Array.IndexOf took 3.531 seconds.

Here's the entire console application for those who are interested:

using System;using System.Collections.Generic;using System.Text;namespace TestFunctions{    class Program    {        public static int GetValueIndex(object[] array, object value)        {            for (int index = 0; index < array.Length; index++)            {                if (array[index] == value)                    return index;            }            return -1;        }        static void Main(string[] args)        {            Random rng = new Random();            object[] o = new object[4096];            for (int i = 0; i < o.Length; i++)            {                o = (object)rng.NextDouble();            }            int valueToTestFor = Convert.ToInt32(o[4000]);            int ss = DateTime.Now.Second;            int sm = DateTime.Now.Millisecond;            for (int n = 0; n < 10000; n++) // 10000 tests            {                GetValueIndex(o, (object)valueToTestFor);            }            int es = DateTime.Now.Second;            int em = DateTime.Now.Millisecond;            Console.WriteLine("[loop] Start:\t" + Convert.ToString(ss) + "." + Convert.ToString(sm));            Console.WriteLine("[loop] End:\t" + Convert.ToString(es) + "." + Convert.ToString(em));            ss = DateTime.Now.Second;            sm = DateTime.Now.Millisecond;            for (int n = 0; n < 10000; n++) // 10000 tests            {                Array.IndexOf(o, (object)valueToTestFor);            }            es = DateTime.Now.Second;            em = DateTime.Now.Millisecond;            Console.WriteLine("[array.indexof] Start:\t" + Convert.ToString(ss) + "." + Convert.ToString(sm));            Console.WriteLine("[array.indexof] End:\t" + Convert.ToString(es) + "." + Convert.ToString(em));            Console.Read();        }    }}
Who cares?

You're using the wrong data structure for searching. At that point, you're using a bucket to bail out the titanic. 7x difference is kinda paltry.

I threw together a quick test:

class Program {        static void Main(string[] args) {            Dictionary<int, int> table = new Dictionary<int, int>();            List<int> list = new List<int>();            int[] arr = new int[100000];            for (int i = 0; i < 100000; ++i) {                arr = i;                list.Add(i);                table.Add(i, i);            }            DateTime Tracker;                        int rslt;            Random rng = new Random();                        Tracker = DateTime.Now;            for (int i = 0; i < 100000; ++i) {                int key = rng.Next(100000);                if (table.ContainsKey(key)) {                    rslt = table[rng.Next(100000)];                }            }            Console.WriteLine( DateTime.Now - Tracker);            Tracker = DateTime.Now;            for (int i = 0; i < 100000; ++i) {                rslt = list.IndexOf(rng.Next(100000));            }            Console.WriteLine(DateTime.Now - Tracker);            Tracker = DateTime.Now;            for (int i = 0; i < 100000; ++i) {                rslt = Array.IndexOf<int>(arr, rng.Next(100000));            }            Console.WriteLine(DateTime.Now - Tracker);        }    }


I used 100,000 elements because I couldn't get results with smaller values. It ran too fast.

Dictionary Search 0.05sList IndexOf 20.63sArray IndexOf 21.07s



Though this assumes that the 'find file in the list' is anywhere near the slowest part of your program, and there's no proof that the OP is suffering there. Indeed, I would be astounded if this one operation is a drop in the bucket compared to Directory.GetFiles()


Or to be brief: use the damned library.
Quote:Original post by Kuraitou
I'm not going to force my opinion, but I took the initiative to test the results between my loop method and Array.IndexOf.

(Using an array with 4096 elements) In 10,000 calls to either function, the loop took 0.188 seconds to execute, and the Array.IndexOf took 0.703 seconds. Similarly, with 50,000 calls, the loop took 0.937 seconds and Array.IndexOf took 3.531 seconds.

Here's the entire console application for those who are interested:

*** Source Snippet Removed ***


I would expect your version to be faster, since the .NET version does checks to ensure that parameters are valid.

Second, your method uses objects, which ends up causing lots of boxing and unboxing, and if I want to test on an array of bools, I need to create a whole new method. The .NET makes use of generics to avoid this mess.

Third, the .NET method is more flexible, with overloads taking parameters to specify different portions of the array to operate on.

Fourth, and perhaps most egregiously, your method won't even actually work; it will always return -1. The operator == of the object class checks for reference equality, which in the case of value types will never be the same. You would need to use Equals to check for value equality.
Mike Popoloski | Journal | SlimDX
I decided to use the Array.IndexOf() method because the only reason I'm even writing this program at all is to learn C#/.NET. The program is just meant to be an easy way to add metadata to JPEGs. I thought is would be a fairly simple way to get used to C# before using XNA.

This topic is closed to new replies.

Advertisement