【发布时间】:2021-08-21 01:56:49
【问题描述】:
我有一个从 CSV 文件导入的数据表。可以导入多种不同的表。
数据表有四列(type=double):LookupColumn L M S
LookupColumn 通常有一个唯一的名称(例如,长度、高度、重量)。其他列名称保持不变。这无关紧要,因为您可以主要使用 dt.Column[0] 。查找列将始终是导入的第一列。
我需要在 LookupColumn 上的数据表中搜索从应用程序(来自文本框)传递的 LookupValue。
如果 LookupValue 与 LookupColumn 中的数字完全匹配,则返回 L、M、S 的值。
如果没有匹配,那么我需要找到 LookupValue 所在位置两侧的行,并返回 L、M、S 中每个变量的最小/最大值。
一旦有了这些,我就可以对 L、M、S 的值进行插值。
例如:
| Col_0 | L | M | S |
|---|---|---|---|
| 45.0 | -0.3521 | 2.441 | 0.09182 |
| 45.5 | -0.3521 | 2.524 | 0.09153 |
| 46.0 | -0.3521 | 2.608 | 0.09124 |
| 46.5 | -0.3521 | 2.691 | 0.09094 |
| 47.0 | -0.3521 | 2.776 | 0.09065 |
| 47.5 | -0.3521 | 2.861 | 0.09036 |
| 48.0 | -0.3521 | 2.948 | 0.09007 |
如果 Col[0] 中的 LookupValue = 46.5,程序将返回 L=-0.3521 M=2.691 S=0.09094
这些值将放在查看者所看到的表单上的文本框中。
如果没有匹配项(假设 LookupValue 在 LookupColumn min/max 范围内),那么我需要返回该值存在时所在位置两侧的行——即 Lmin Lmax、Mmin Mmax , Smin Smax 并使用以下公式中的那些得到 LookupColumn (Col_0) 的插值 (IntVal)。
例如,如果 (Col_0) 中的 LookupValue = 46.8,则返回的结果(数组?列表?)将是 Col_0 = 46.5 和 47.0 的行:
| Col_0 | L Values | M Values | S Values |
|---|---|---|---|
| LookupMin = 46.5 | Lmin = -0.3521 | Mmin = 2.691 | Smin = 0.09094 |
| LookupMax = 47.0 | Lmax = -0.3521 | Mmax = 2.776 | Smax = 0.09065 |
插值 = LMSmin + (46.8 - LookupMin) * (LMSmax - LMSmin / LookupMax - LookupMin)
插值 L = -0.3521,因为 Lmin = Lmax
插值 M = 2.691 + (46.8 - 46.5) * (2.776 - 2.691 / 47.0 - 46.5)
插值 M = 2.7418
插值 S = 0.09094 + (46.8 - 46.5) * (0.09065 - 0.09094 / 47.0 - 46.5)
插值 S = 0.09088
因此,给定 Col_0 的 Min/Max 值以及 L、M 或 S 的 min/max 值,我可以插入用户提供的任何不在查找中的值,即使 LookupValue 有更多小数。插值后的 L、M、S 值将被放入用户的文本框中。
我有一些代码可以在匹配时工作,但是,我认为使用 Linq 或 Tuples 有更好/更简洁的方法。我意识到这不是最好的代码,我愿意接受建议。
我搜索了 StackOverflow 并找到了几篇关于插值和查找表的帖子。查找的最佳实践似乎是使用元组,但是,我对它们的使用不是很清楚。
在大多数情况下,这个问题的重点是在没有匹配项时返回查找的最小值/最大值。一旦我有了这些,我不认为插值是一个伟大的壮举,因为我知道这个公式。另外,我知道用户可以输入超出范围的值——我稍后会解释这些问题。
感谢任何帮助。
private void tbLookup_Leave(object sender, System.EventArgs e)
{
string colName = tmpDT.Columns[0].ColumnName;
string colSearch = colName + " = '" + tbLookup.Text + "'";
if (tbLookup.Text.Length > 0)
{
// Exact match
while (true)
{
DataRow[] foundRow = tmpDT.Select(colSearch);
if (foundRow.Length == 0)
{
break;
}
foreach (DataRow row in foundRow)
{
string L = row.Field<string>("L");
string M = row.Field<string>("M");
string S = row.Field<string>("S");
tbLkupL.Text = L;
tbLkupM.Text = M;
tbLkupS.Text = S;
}
// No match
// Call interpolation method
}
}
else
{
MessageBox.Show("Please enter a lookup value", "Missing Data");
}
【问题讨论】:
标签: c# tuples interpolation lookup-tables