Reputation: 115
I'm trying to retrieve the closest lower value from a datagridview based on input from a user.
For example, I have these two rows of data:
dgvKeyFactorTable.Rows.Add(new object[] { 00000m, 1.000m });
dgvKeyFactorTable.Rows.Add(new object[] { 150000m, 1.873m });
dgvKeyFactorTable.Rows.Add(new object[] { 155000m, 1.938m });
If the user inputs 150000, the program correctly references 1.873 with this statement:
var _factorKeyVariable = this.dgvKeyFactorTable.Rows.Cast<DataGridViewRow>()
.Where(r=>(decimal)r.Cells[0].Value == decimal.Parse(txtCoverageA.Text))
.Select(r=>(decimal)r.Cells[1].Value)
.FirstOrDefault();
factorKey = _factorKeyVariable;
lblKeyFactor.Text = factorKey.ToString();
However, I need to be able to have a user input a number that is between the values in this table - for example, 153500, and have the program set the factorKey
variable according to a formula.
In order for the formula to succeed, I need to reference the closest highest numbers (155000 & 1.938) which I successfully do here:
var _factorKeyHigh = dgvKeyFactorTable.Rows.Cast<DataGridViewRow>()
.Where(r => (decimal)r.Cells[0].Value >= decimal.Parse(txtCoverageA.Text))
.Select(r => (decimal)r.Cells[1].Value)
.FirstOrDefault();
var _keyFactorCoverageHigh = dgvKeyFactorTable.Rows.Cast<DataGridViewRow>()
.Where(r => (decimal)r.Cells[0].Value >= decimal.Parse(txtCoverageA.Text))
.Select(r => (decimal)r.Cells[0].Value)
.FirstOrDefault();
And, I also need to capture the closest lowest values in the table (150000 & 1.873). This is where I'm having trouble. I'm using this code to attempt to do so:
var _factorKeyLow = dgvKeyFactorTable.Rows.Cast<DataGridViewRow>()
.Where(r => (decimal)r.Cells[0].Value <= decimal.Parse(txtCoverageA.Text))
.Select(r => (decimal)r.Cells[1].Value)
.FirstOrDefault();
var _keyFactorCoverageLow = dgvKeyFactorTable.Rows.Cast<DataGridViewRow>()
.Where(r => (decimal)r.Cells[0].Value <= decimal.Parse(txtCoverageA.Text))
.Select(r => (decimal)r.Cells[0].Value)
.FirstOrDefault();
However, this is always returning the lowest value in the table 0, 1.000. I'm not sure why this isn't working, can anyone provide some insight?
Upvotes: 1
Views: 111
Reputation: 19149
To get the highest you can do this. I have simplified the query so its more readable and also faster. because you dont have to find one item twice.
var highfactor= dgvKeyFactorTable.Rows.Cast<DataGridViewRow>()
.FirstOrDefault(r => (decimal)r.Cells[0].Value >= decimal.Parse(txtCoverageA.Text));
var _keyFactorCoverageHigh = (decimal)highfactor.Cells[0].Value;
var _factorKeyHigh = (decimal)highfactor.Cells[1].Value;
But to get the lowest remember that 00000m, 1.000m
is also lower and its lower than 150000m, 1.873m
so FirstOrDefault();
will give you this because its the first find. Instead use LastOrDefault();
to get closest item.
Note that LastOrDefault
also gives you the first find but it will search from end to beginning.
var lowfactor= dgvKeyFactorTable.Rows.Cast<DataGridViewRow>()
.LastOrDefault(r => (decimal)r.Cells[0].Value <= decimal.Parse(txtCoverageA.Text));
var _keyFactorCoverageLow = (decimal)lowfactor.Cells[0].Value;
var _factorKeyLow = (decimal)lowfactor.Cells[1].Value;
Upvotes: 1
Reputation: 196
FirstOrDefault returns the first element of the sequence. You're retrieving the first element from the sequence of table entries less than your input value.
You can use LastOrDefault instead for the less-than case. This returns the last element of the sequence, and should be what you're looking for as long as the sequence is ordered from least to greatest.
Upvotes: 1