3

I have two lists in my program that the length of the lists is not equal. I want to subtract the members of these two lists element by element and save them in one list.

            List<double> arrivals = new List<double>();
            List<double> departure = new List<double>();
            List<double> delays = new List<double>();
            double departure_p = 0.8;
            double arrival_p = 0.45;
            int slot = 0;
            while (slot < 1000)
            {
                Random a = new Random();
                double arrival_t = a.NextDouble();
                Random d = new Random();
                double departure_t = d.NextDouble();

                if (departure_t <= departure_p)
                {
                    departure.Add(departure_t);
                }
                if (arrival_t <= arrival_p)
                {
                    arrivals.Add(arrival_t);
                }
                slot++;
           }

When I use this method I encounter the exception system.IndexOutOfRangeException.


for (int i = 0; i <= arrivals.Count; i++)
            {
                delays.Add(departure[i] - arrivals[i]);
            }
            foreach (var item in delays)
                Console.WriteLine(item);

How can I do this?

zahrakhani
  • 267
  • 3
  • 17
  • 1
    Whoever upvotes this post next please [edit] to clarify what OP wanted to achieve if lists are of different length. They did not clarify it in yesterday version... so hopefully one figured by now what they wanted. – Alexei Levenkov Apr 13 '21 at 18:35
  • 1
    Your requirements seem incomplete. What is the desired behavior when one list has more elements than the other? Doesn't make much sense to do pairwise subtraction when you don't actually have pairs. Should we only include matching pairs? Should we treat unarrived flights as arriving at `DateTime.Now`? Etc. – John Wu Apr 13 '21 at 18:36
  • 1
    `for (int i = 0; i < Math.Min(arrivals.Count, depart.Count); i++) {...}` – Dmitry Bychenko Apr 13 '21 at 18:40
  • `new Random().NextDouble()` always gets the same result, you need to cache the `Random` object – Charlieface Apr 13 '21 at 19:40

2 Answers2

11

If you write i <arrivals.Count in the for loop, the problem will be solved. You can also use the Zip method in Linq.

var delay = departure.Zip(arrivals, (depart, arri) => depart - arri);
            
            foreach (var item in delay)
            {
                Console.WriteLine(item);
            }
zahrakhani
  • 267
  • 3
  • 17
2

Well, IndexOutOfRangeException means that index i exceeds Count of either departure or arrivals so departure[i] - arrivals[i] becomes illegal. You can amend the for loop as

for (int i = 0; i < Math.Min(arrivals.Count, depart.Count); i++)
  delays.Add(departure[i] - arrivals[i]); 

foreach (var item in delays)
  Console.WriteLine(item);

with i < Math.Min(arrivals.Count, depart.Count) conditon we now guarantee, that i will never be beyond both departure and arrivals

Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215