如何在 C# 中根据另一列的值比较返回第一列的行值?

问题描述 投票:0回答:2

我对 C# 世界相当陌生,需要帮助找出解决方案。我正在编写一个程序,其中包含一个格式如下的数据表:

返回 100 200 300 400
A 1 2 3 4
B 2 3 4 5
C 3 4 5 6
D 4 5 6 7

我让用户输入他们想要搜索的列,比如“300”,他们还输入一个数字。假设搜索是从上到下完成的,如果该数字小于第一个值,它应该返回同一行的第一列值。

那么,让我们继续使用“300”作为搜索栏。如果用户输入 4.7,我希望返回“C”,因为 4.7 小于或等于 5。100-400 列中的值将始终按从最低到最高的顺序排列。我知道这必须是可能的,但过去几个小时试图弄清楚如何对值进行逻辑比较给我带来了困难,并且感谢任何帮助或指导。

我应该注意,我在另一个函数中使用这个数据表几乎是做相反的事情,所以我不想重组这个数据表,因为我已经花了时间创建它。

c# datatable
2个回答
0
投票

您可以使用 LINQ,我用您的示例编写了一个控制台项目,在此我使用 LINQ 和 Math Floor、Ceiling 和 round,您可以与您的业务逻辑一起使用:

using System;
using System.Data;
using System.Linq;

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            DataTable dt = new DataTable("MyDataTable");
            dt.Columns.Add("Return");
            dt.Columns.Add("100");
            dt.Columns.Add("200");
            dt.Columns.Add("300");
            dt.Columns.Add("400");
            dt.Rows.Add("Un", 1, 2, 3, 4);
            dt.Rows.Add("B", 2, 3, 4, 5);
            dt.Rows.Add("C", 3, 4, 5, 6);
            dt.Rows.Add("D", 4, 5, 6, 7);

        Again:
            Console.WriteLine($"Write Column[100, 200, 300, 400]:");
            var SearchColumn = Console.ReadLine();

            Console.WriteLine($"Write value:");
            double val;
            bool isDouble = double.TryParse(Console.ReadLine(), out val);
            if (!isDouble) goto notShow;
            string returned;

            // Return First 5 for 4.7, Return "C"
            returned = dt.Select().FirstOrDefault(o => int.Parse(o[SearchColumn].ToString()) == Math.Floor(val))[0].ToString();

            Console.WriteLine($"Math.Floor: {returned}");

            // Return First 4 for 4.7, Return "B"
            returned = dt.Select().FirstOrDefault(o => int.Parse(o[SearchColumn].ToString()) == Math.Ceiling(val))[0].ToString(); ;
            Console.WriteLine($"Math.Ceiling: {returned}");

            // Return First 5 for 4.7, Return "C"
            returned = dt.Select().FirstOrDefault(o => int.Parse(o[SearchColumn].ToString()) == Math.Round(val))[0].ToString(); ;
            Console.WriteLine($"Math.Round: {returned}\n\n");

            goto Again;
        notShow:
            Console.WriteLine("Error: not is valid");
            goto Again;
        }
}

这些行在行集合中搜索并返回第一列的值:

        returned = dt.Select().FirstOrDefault(o => int.Parse(o[SearchColumn].ToString()) == Math.Floor(val))[0].ToString();

        returned = dt.Select().FirstOrDefault(o => int.Parse(o[SearchColumn].ToString()) == Math.Ceiling(val))[0].ToString(); ;

        returned = dt.Select().FirstOrDefault(o => int.Parse(o[SearchColumn].ToString()) == Math.Round(val))[0].ToString(); ;

0
投票

使用 LINQ,我获得了大于或等于输入值的所有行,并选择了第一个行。根据问题,列值已经按升序排列。

// Create a sample DataTable
DataTable dt = new DataTable("tbl");
DataColumn dtColumn;
dtColumn = new DataColumn();
dtColumn.DataType = typeof(string);
dtColumn.ColumnName = "Return";
dtColumn.ReadOnly = false;
dtColumn.Unique = true;
dt.Columns.Add(dtColumn);


dtColumn = new DataColumn();
dtColumn.DataType = typeof(Int32);
dtColumn.ColumnName = "100";
dtColumn.ReadOnly = false;
dtColumn.Unique = true;
dt.Columns.Add(dtColumn);

dtColumn = new DataColumn();
dtColumn.DataType = typeof(Int32);
dtColumn.ColumnName = "200";
dtColumn.ReadOnly = false;
dtColumn.Unique = true;
dt.Columns.Add(dtColumn);

dtColumn = new DataColumn();
dtColumn.DataType = typeof(Int32);
dtColumn.ColumnName = "300";
dtColumn.ReadOnly = false;
dtColumn.Unique = true;
dt.Columns.Add(dtColumn);

DataRow dr = dt.NewRow();
dt.Rows.Add(dr);
dr["Return"] = "A";
dr["100"] = 1;
dr["200"] = 2;
dr["300"] = 3;

dr = dt.NewRow();
dt.Rows.Add(dr);
dr["Return"] = "B";
dr["100"] = 2;
dr["200"] = 3;
dr["300"] = 4;

dr = dt.NewRow();
dt.Rows.Add(dr);
dr["Return"] = "C";
dr["100"] = 3;
dr["200"] = 4;
dr["300"] = 5;

dr = dt.NewRow();
dt.Rows.Add(dr);
dr["Return"] = "D";
dr["100"] = 4;
dr["200"] = 5;
dr["300"] = 6;

double inputVal = 4.7;
// The Column data is already ordered , as mentioned in the question
var t1 = dt.AsEnumerable().Where(r1 => r1.Field<int>("300") >= inputVal)  // all records greater than the input value
                          .Select(a => a[0]).ToList() // select value from first column
                          .FirstOrDefault();  // the closest one
© www.soinside.com 2019 - 2024. All rights reserved.