tags:

views:

284

answers:

4

I'm trying to find an item in a list of values based on another value using a lambda expression using the Find method. In this example I'm expecting to get back -1000, but for the life of me, I just can't come up with the proper lamda expression. If that sounds confusing I hope the code and comments below explain it better. TIA.

using System;
using System.Collections.Generic;

namespace TestingStuff {
    class Program {
        static void Main(string[] args) {
            double amount = -200;

            //The Range of values
            List<MyValue> values = new List<MyValue>();
            values.Add(new MyValue(-1000));
            values.Add(new MyValue(-100));
            values.Add(new MyValue(-10));
            values.Add(new MyValue(0));
            values.Add(new MyValue(100));
            values.Add(new MyValue(1000));

            //Find it!!!  
            MyValue fVal = values.Find(x => (x.Value > amount) && (x.Value < amount));

            //Expecting -1000 as a result here since -200 falls between -1000 and -100
            //if it were -90 I'd expect -100 since it falls between -100 and 0
            if (fVal != null)
                Console.WriteLine(fVal.Value);            
            Console.ReadKey();
        }
    }

    public class MyValue {
        public double Value { get; set; }
        public MyValue(double value) {
            Value = value;
        }        
    }
}

Mmm let me put my intentions a little clearer by specifying all the expected results.

-1000 and less to -101 should give -1000
-100 to - 11 should give -100
-10 to -1 should give -10
0 to 9 should give 0
10 to 99 should give 10
100-999 should give 100
1000 or more should give 1000

+2  A: 

You did a logical mistake ... a value can't be > -200 AND < -200 at the same time .. U need the OR expression ( "||" )

 MyValue fVal = values.Find(x => (x.Value > amount) || (x.Value < amount));

But if you expect to get -1000 this expression is also wrong

 MyValue fVal = values.Find(x => (x.Value < amount));

Because -1000 is SMALLER than -200

EDIT : Ok I think I missunderstood your intention. But the way you want to select your value doesn't seem logical to me. Do you want the next smaller value ?

KroaX
I have updated the main question, with all the expected results. Please see there. What I basically want is to do a between like you would in a SQL statement when searching for results that fall between two dates except these are numbers.EG:SELECT * FROM UsersWHERECreationDate > '2010-03-01'AND CreationDate < '2010-03-31'Which finds all users between 1 Mar and 31 Mar.Hope this makes sense
n4rzul
A: 

I'm making the assumption that if you used the value +90, you'd expect 100 and not zero, as well as if you use 200, you're expecting 1000 and not 100.

MyValue fVal = values
    .Where(x => amount > 0 ? x.Value > amount : x.Value < amount)
    .OrderBy(x => amount > 0 ? x.Value : -x.Value).First();
Darksider
nope, other way round
n4rzul
+1  A: 

This should work:

values.FindLast(x => amount >= x.Value);
Julien Lebosquain
Awesome this is percect. How elegant!
n4rzul
Hold on, maybe not 100% this caters for all the instance even 10000000 which should give 1000 but it does not cater for -100000 which should give -1000. I could just add a very very large negative value to the start of my list though and it should work fine.
n4rzul
A: 

Making the same assumption as Darksider Another option would be

            MyValue fVal = values.Find(x => Math.Abs(x.Value) > amount && (x.Value<0 == amount<0));

of course this relies on the list already being sorted. Darksider's solution may be better if the list might not be sorted alreday.

Joe90
Julien's works correctly in my case except for very small negative values. I'll just add a very small negative value in the list and all should be fine.
n4rzul