为了账号安全,请及时绑定邮箱和手机立即绑定

c#使用一个变量值从固定列表中设置第二个

c#使用一个变量值从固定列表中设置第二个

C#
有只小跳蛙 2022-06-12 14:46:37
我在 ac# .net windows form 应用程序中解析一个 CSV 文件,将每一行放入我创建的类中,但是我只需要访问一些列并且所采用的文件不是标准化的。也就是说,存在的字段数可能不同,并且列可以出现在任何列中。CSV 示例 1:Position, LOCATION, TAG, NAME, STANDARD, EFFICIENCY, IN USE,,1, AFT-D3, P-D3101A, EQUIPMENT 1, A, 3, TRUE2, AFT-D3, P-D3103A, EQUIPMENT 2, B, 3, FALSE3, AFT-D3, P-D2301A, EQUIPMENT 3, A, 3, TRUE...CSV 示例 2:Position, TAG, STANDARD, NAME, EFFICIENCY, LOCATION, BACKUP, TESTED,,1, P-D3101A, A, EQUIPMENT 1, 3, AFT-D3, FALSE, TRUE2, P-D3103A, A, EQUIPMENT 2, 3, AFT-D3, TRUE, FALSE3, P-D2301A, A, EQUIPMENT 3, 3, AFT-D3, FALSE, TRUE...正如你所看到的,我永远不会知道我必须分析的文件的格式,我唯一确定的是它总是包含我需要的几列。我对此的解决方案是要求用户输入所需的列并将其设置为字符串,使用他们的条目将其转换为相应的整数,然后我可以将其用作位置。string standardInpt = "";string nameInpt = "";string efficiencyInpt = "";然后用户将输入一个从 A 到 ZZ 的值。int standardLocation = 0;int nameLocation = 0;int efficiencyLocation = 0;提交表单时。整数通过运行 if else... 语句获得最终值:if(standard == "A"){  standardLocation = 0;}else if(standard == "B") {  standardLocation = 1;}...等一直运行到 if VAR1 == ZZ 然后对 VAR2 和 VAR3 等重复代码。我的课程部分看起来像:class Equipment{  public string Standard { get; set;}  public string Name { get; set; }  public int Efficiency { get; set; }  static Equipment FromLine(string line)  {     var data = line.split(',');     return new Equipment()     {      Standard = data[standardLocation],      Name = [nameLocation],      Efficiency = int.Parse(data[efficiencyLocation]),     };   }}我有更多的代码,但我认为这突出了我将使用变量来设置索引的地方。我对此很陌生,我希望必须有一种更好的方法来实现这一点,而不必编写太多可能过多的重复 If Else 逻辑。我正在考虑某种查找表,但我无法弄清楚如何实现这一点,任何关于我可以查看的指针?
查看完整描述

3 回答

?
慕田峪4524236

TA贡献1875条经验 获得超5个赞

您可以使用反射和属性。


将您的样本,分开写入DisplayName属性。


首先调用GetIndexescsv 头字符串作为参数,获取类属性和 csv 字段的映射字典。


然后调用FromLine每一行和你刚刚得到的映射字典。


class Equipment

{

    [DisplayName("STND, STANDARD, ST")]

    public string Standard { get; set; }

    [DisplayName("NAME")]

    public string Name { get; set; }

    [DisplayName("EFFICIENCY, EFFI")]

    public int Efficiency { get; set; }

    // You can add any other property


    public static Equipment FromLine(string line, Dictionary<PropertyInfo, int> map)

    {

        var data = line.Split(',').Select(t => t.Trim()).ToArray();

        var ret = new Equipment();

        Type type = typeof(Equipment);

        foreach (PropertyInfo property in type.GetProperties())

        {

            int index = map[property];

            property.SetValue(ret, Convert.ChangeType(data[index],

                property.PropertyType));

        }

        return ret;

    }


    public static Dictionary<PropertyInfo, int> GetIndexes(string headers)

    {

        var headerArray = headers.Split(',').Select(t => t.Trim()).ToArray();

        Type type = typeof(Equipment);

        var ret = new Dictionary<PropertyInfo, int>();

        foreach (PropertyInfo property in type.GetProperties())

        {

            var fieldNames = property.GetCustomAttribute<DisplayNameAttribute>()

                .DisplayName.Split(',').Select(t => t.Trim()).ToArray();

            for (int i = 0; i < headerArray.Length; ++i)

            {

                if (!fieldNames.Contains(headerArray[i])) continue;

                ret[property] = i;

                break;

            }

        }

        return ret;

    }

}


查看完整回答
反对 回复 2022-06-12
?
开满天机

TA贡献1786条经验 获得超13个赞

您可以通过在标题中查找列的索引来使其自动化,然后使用它们从其余行的正确位置读取值:


class EquipmentParser {

    public IList<Equipment> Parse(string[] input) {

        var result = new List<Equipment>();


        var header = input[0].Split(',').Select(t => t.Trim().ToLower()).ToList();

        var standardPosition = GetIndexOf(header, "std", "standard", "st");

        var namePosition = GetIndexOf(header, "name", "nm");

        var efficiencyPosition = GetIndexOf(header, "efficiency", "eff");


        foreach (var s in input.Skip(1)) {

            var line = s.Split(',');

            result.Add(new Equipment {

                Standard = line[standardPosition].Trim(),

                Name = line[namePosition].Trim(),

                Efficiency = int.Parse(line[efficiencyPosition])

            });

        }


        return result;

    }


    private int GetIndexOf(IList<string> input, params string[] needles) {

        return Array.FindIndex(input.ToArray(), needles.Contains);

    }

}


查看完整回答
反对 回复 2022-06-12
?
慕后森

TA贡献1802条经验 获得超5个赞

如果有帮助,试试这个:


    public int GetIndex(string input)

    {

        input = input.ToUpper();

        char low = input[input.Length - 1];

        char? high = input.Length == 2 ? input[0] : (char?)null;

        int indexLow = low - 'A';

        int? indexHigh = high.HasValue ? high.Value - 'A' : (int?)null;

        return (indexHigh.HasValue ? (indexHigh.Value + 1) * 26 : 0) + indexLow;

    }


查看完整回答
反对 回复 2022-06-12
  • 3 回答
  • 0 关注
  • 111 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信