1

I have searched through the StackOverflow yet couldn't find my question.

I have some data like this:

object a -> min:3 max:13
object b -> min:11 max:20
object c -> min:16 max:21
...
z-> min:200 max:250

For a specified interval, I expect a, b, c or other objects or a list.

For example if (6,8) is passed then I want to have "a", if (12,13) is passed I want to have a list of "a and b", if (17, 20) is passed I want to have a list of "b and c" and if (3,250) then I want to have a list of all.

I don't know in which type of collection I should store the values (3, 13, object a) and others.

Can you name the collection and give an example?

Thanks in advance...

p.s. sorry if I couldn't describe well because of my English and thank you all

  • I'm not entirely sure what your asking, but you should look at either a `Dictionary, KeyValuePair, or a Tuple`. – Greg Mar 04 '15 at 15:04
  • possible duplicate of [A dictionary object that uses ranges of values for keys](http://stackoverflow.com/questions/2147505/a-dictionary-object-that-uses-ranges-of-values-for-keys) – mmg666 Mar 04 '15 at 15:13
  • 1
    I don't know how this question is related to a dictionary. – Tim Schmelter Mar 04 '15 at 15:14
  • You need to specify your requirements a little better. Most people are assuming you want ranges that completely include the given range, but I believe you actually want any ranges that intersect with the given range. – juharr Mar 04 '15 at 15:18
  • If you want search ranges in a collection then the answer by @TimSchmelter below would do it for you, but I'm not certain that's what you are looking for. If you want multiple values to equate to a key of a dictionary, then you'd have to write your own data structure to do this. – JNYRanger Mar 04 '15 at 15:20
  • If your intervals overlap you can implement (or locate an already made) [Interval Tree](http://en.wikipedia.org/wiki/Interval_tree). If they never overlap then you can build a structure on top of a SortedList and calculate the actual key\index value when a value within your interval is provided. – JNYRanger Mar 04 '15 at 15:24
  • It's not related to a dictionary, of course the OP can implement this in many ways but what is described is an Interval Tree imho. – mmg666 Mar 04 '15 at 15:54

4 Answers4

1

So you want to find objects where the min value is smaller/equal the passed min-value and the max value is larger/equal the passed max-value.

var query = objects.Where(obj=> obj.MinVal <= minVal && obj.MaxVal >= maxVal);

Can you name the collection and give an example?

So you don't have a collection? You should fill a List<Range> where Range is a custom class with at least two properties MinVal and MaxVal.

Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
  • 1
    The OP states that "(3,250) then I want to have a list of all." So I believe they want ranges that intersect the given range, not ranges contain the given range. – juharr Mar 04 '15 at 15:19
1

You can either create your own type or you can use Tuple<int, int> to represent one object. Then you can create and populate a List of these objects to store your entire collection. After that you can use LINQ to query for the desired objects:

List<Tuple<int, int>> YourCollection = new List<Tuple<int, int>>();
YourCollection.Add(new Tuple<int, int>(3, 13));
YourCollection.Add(new Tuple<int, int>(11, 20));
YourCollection.Add(new Tuple<int, int>(16, 21));

var Results = YourCollection.Where(x => x.Item1 <= MAX && MIN <= x.Item2);

where MIN and MAX define the range that you're interested in. Note that the condition above looks for overlapping (intersection) as appears to be what is needed.

dotNET
  • 33,414
  • 24
  • 162
  • 251
1
void Main()
{
    var input = new List<Interval>
    {
        new Interval { Name = "a", Min = 3, Max = 13 },
        new Interval { Name = "b", Min = 11, Max = 20 },
        new Interval { Name = "c", Min = 16, Max = 21 },
        new Interval { Name = "z", Min = 200, Max = 250 }
    };

    var interval = new Interval { Name = "search", Min = 12, Max = 13 };

    // Don't forget the third case when the interval 
    // you're looking for is inside your input intervals
    // Min = 210, Max = 220 should return "z"
    var result = input.Where(i => (interval.Min <= i.Min && i.Min <= interval.Max) ||
                                  (interval.Min <= i.Max && i.Max <= interval.Max) ||
                                  (i.Min <= interval.Min && interval.Max <= i.Max));
}

class Interval
{
    public string Name;
    public int Min;
    public int Max;
}
aush
  • 2,108
  • 1
  • 14
  • 24
0

sing a fork of @aush code it will be bettler if you can inherint the class System.Collections.CollectionBase then you can make an easy foreach implementing this class.

structure Interval{
    public string Name;
    public int Min;
    public int Max;

    public Interval(string Name,int Min,int Max){
     this.Name = Name;
     this.Min = Min;
     this.Max = Max;
    }
    public bool IsInsideOfRange(int value){
        if(value >= this.Min && value <= this.Max){
           return true;
        }else{
           return false;
        }
    }
    public overrides ToString(){
      return this.Name;
    }

}

class IntervalCollection : System.Collections.CollectionBase {

   public void Add(string Name,int Min,int Max){
    Interval Item = new Interval(Name,Min,Max);
    this.List.Add(Item);
   }
   public void Add(Interval Item){
    this.List.Add(Item);
   }


   public string Encode(param int[] values){
       string EcodedText = "";
        foreach(int iValue in values){
           foreach(Interval Item in this){
                if(Item.IsInsideOfRange(iValue)){
                   EncodedText +=Item.ToString();
                }
           }
        }
       return EcodedText;
   }

}

you can implement this class like this

IntervalCollection Intervals = new IntervalCollection();
string EncodeText  = "";
Intervals.Add(new Interval { Name = "a", Min = 3, Max = 13 });
Intervals.Add(new Interval { Name = "b", Min = 11, Max = 20 });
Intervals.Add(new Interval { Name = "c", Min = 16, Max = 21 });
Intervals.Add( "z", 200, 250 }); //you can add item in this way too.

EncodeText = Intervals.Encode(6,8,12,13,17,20);
MrAlex6204
  • 167
  • 7