Find match between two lists in C #

I have matlab code that calculates the overlap of two lists. This actually checks if list H is inside another list U and keeps a list box U where list H is inside (at least once). Actually U, H is an Nx2 indexed list, where at each point there are two values ​​for the starting window index and the ending window index. My code in Matlab:

function W = getwindowsspecial(U,H)
W = [];
for i = 1:size(U,1)
  if any(H(:,1)>=U(i,1) & H(:,1)<=U(i,2))
    W = [W;U(i,:)];
  end
end

      

For example, U could be:

54  86
112 217
292 325
402 451
628 664

      

H can be:

129 214
297 321
406 447
637 664

      

and the result of W is:

112 217
292 325
402 451

      

I want to convert this code to C #. My list U, H is presented as a list ->. My corresponding function is as follows:

 static List<int> getWindows(List<List<int>> list1, List<List<int>> list2)
    {
        List<int> list3 = new List<int>();

        for (int index = 0; index < list1[0].Count; index++) { 

        }

            return list3;
    }

      

What should I fill in with my function to work like Matlab?

EDIT: In this code, I am adding limits for the first and second list. How can these constraints be added to a Tuple instead of a list of lists?

        List<List<int>> first = new List<List<int>>();
        List<List<int>> second = new List<List<int>>();
        first.Add(upFirst); first.Add(downFirst);
        second.Add(upSecond); second.Add(downSecond);

        getWindows(first, second);

      

upFirst and upSecond contains all the left limits for the first and second lists and downFirst and downSecond contains all the correct limits for the first and second lists. I tried to use the following code to get my job done:

 for (int index = 0; index < upFirst.Count; index++){

            first.Add(new List<int> { upFirst[index], downFirst[index] });

 }

 for (int index = 0; index < upSecond.Count; index++){

           second.Add(new List<int> { upSecond[index], downSecond[index]});

  }
  List<List<int>> lista = GetWindows(first, second);

      

This is what I tried to add as tuples. However, using @M. Nasser Jawid, I got NULL. The input I provide for a list of first and second lists is as follows:enter image description here

+3


source to share


2 answers


Try this please. For this scenario, we need numbers from U that are in the range H, so they ...

public void Test()
    {
        var listU = new List<List<int>>
        {
            new List<int> {54, 86},
            new List<int> {112, 217},
            new List<int> {292, 325},
            new List<int> {402, 451},
            new List<int> {628, 664}
        };
        var listH = new List<List<int>>
        {
            new List<int> {129, 214},
            new List<int> {297, 321},
            new List<int> {406, 447},
            new List<int> {637, 664}
        };
        GetWindows(listU, listH);
    }

static List<List<int>> GetWindows(List<List<int>> listU, List<List<int>> listH)
    {
        List<List<int>> list3 = new List<List<int>>();
        var startingOfH = listH.First()[0];
        var endOfH = listH.Last()[listH.Last().Count - 1];
        foreach (var num in listU)
        {
            var initial = num[0];
            var final = num[num.Count - 1];
            if (initial > startingOfH && final < endOfH)
            {
                list3.Add(num);
            }
        }
        return list3;
    }

      

Edit: If you want to use Linq use this

static List<List<int>> GetWindows(List<List<int>> listU, List<List<int>> listH)
    {
        var startingOfH = listH.First()[0];
        var endOfH = listH.Last()[listH.Last().Count - 1];
        return (from num in listU 
                let initial = num[0] 
                let final = num[num.Count - 1] 
                where initial > startingOfH && final < endOfH 
                select num).ToList();
    }

      



Edit 2: Ignore the initial value

static List<List<int>> GetWindows(List<List<int>> listU, List<List<int>> listH)
    {
        List<List<int>> list3 = new List<List<int>>();
        var startingOfH = listH.First()[0];
        var endOfH = listH.Last()[listH.Last().Count - 1];
        foreach (var num in listH)
        {
            var final = num[num.Count - 1];
            if (final > startingOfH && final < endOfH)
            {
                list3.Add(num);
            }
        }
        return list3;
    }

      

If you like Linq then

static List<List<int>> GetWindows(List<List<int>> listU, List<List<int>> listH)
    {
        var startingOfH = listH.First()[0];
        var endOfH = listH.Last()[listH.Last().Count - 1];
        return (from num in listH 
                let final = num[num.Count - 1] 
                where final > startingOfH && final < endOfH 
                select num).ToList();
    }

      

+3


source


You can do this with multiple LINQ queries on the two lists. To make it a little easier, I will assume you have lists of tuples, i.e. List<Tuple<int, int>>

s, not lists of lists.

var W = U.Where(u => H.Any(h => h.Item1 >= u.Item1 && h.Item1 <= u.Item2));

      

Note that this repeats the logic in your MATLAB example, but does not produce the results you provide in your example. If you want to replicate the sample, change the second condition to h.Item2 < u.Item2

i.e. Look at the end of an element from H and demand a strict inequality.


Tuple

vs List

s



If they Tuple<int,int>

feel strange, don't worry - they are very easy to build:

var t = Tuple.Create(2, 3);

      

Depending on where you get the data from, this shouldn't be frustrating. If, however, you already have your data as List<List<int>>

s, you can easily change the condition to use h[0]

instead h.Item1

, etc.

The main reason I suggest tuples is that they will be much more efficient, especially if you have many rows in your matrices U

and H

.

+4


source







All Articles