Как бы вы реализовали общий случай для сопоставления этого свойства с сериализуемым объектом класса?

#c# #linq

#c# #linq

Вопрос:

ОБНОВЛЕНИЕ: используя временные составляющие из моего объекта класса, итератор использовался в качестве обходного пути для проблемы z [index] внутри лямбда-выражений, приведенных ниже.

Вот фрагмент:

 var yValues = new List<Schema.W[]>();
Schema.W[] y = null;
for (int i = 0; i < headers.Length; i  )
    {
        y= data
            .Select((z) => new Schema.W
                {
                    property_0 = z[0],
                    property_1 = decimal.Parse(z[i   1])
                }).ToArray();
                    yValues.Add(y);
                }
    }
 

И затем, наконец:

 var finalList = new List<Schema.W>();
Schema.W = null;
for (int i = 0; i < headers.Length; i  )
    {
        mapping = new Schema.W
        {
            innerNodes = yValues[i]
        };
                finalList.Add(mapping);
    }
 

Обновление: найдено решение LINQ. Проверка кода завершена за пределами сайта.

Я использовал средства сериализации в .NET для преобразования файла * .XML в объект класса, который представляет модель данных стороннего приложения черного ящика.

Используя LINQ, я смог сопоставить заголовки столбцов матрицы данных с их составляющими свойствами, находящимися в этом объекте класса, и сериализовать их во временный тестовый файл * .XML с хорошими результатами. Решение было следующим:

 Schema.W[] mapping = headers
                .Select((x, index) => new Schema.W
                {
// String headers (except for the first column) - "Dates" are excluded from headers 
                    property_0 = headers[index], 
                    property_1 = y
                }).ToArray();

Schema.Entry[] y = data
                 .Select((z, index) => new W.Entry
                 {
                     property_0 = z[0],
                     property_1= decimal.Parse(z[index]) // breaks when z[index]
                }).ToArray();
 

Однако, когда я пытаюсь применить ту же идиому к y, возникает проблема с индексатором. Для первого свойства («Date») внутреннего XML-узла, в который я сопоставляю, сопоставление свойств работает правильно, поскольку это первый столбец моей матрицы данных и обозначается жестко заданным значением (например, z[0]).

Однако мое второе свойство («Значение») сталкивается с (а) проблемой, выходящей за рамки Value = decimal.Parse(z[index]) и (б) проблемой типа, когда я пытаюсь извлечь отдельные значения с этапа обработки, на котором я сохраняю числовую информацию вIEnumerable . Проблема возникает, когда я пытаюсь записать номера каждого столбца в поле property_1, которое позже выводится в сериализованный XML-файл со следующей структурой:

 <W>
  <Overrides>
      <Entry>
        <property_0>2001-01</property_0>
        <property_1>90.01</property_1>
      </Entry>
      <Entry>
        <property_0>2002-01</property_0>
        <property_1>90.02</property_1>
      </Entry>
      <Entry>
        <property_0>2003-01</property_0>
        <property_1>90.03</property_1>
      </Entry>
  </Overrides>
</W>
<W>
  <Overrides>
      <Entry>
        <property_0>2001-01</property_0>
        <property_1>90.01</property_1>
      </Entry>
      <Entry>
        <property_0>2002-01</property_0>
        <property_1>90.02</property_1>
      </Entry>
      <Entry>
        <property_0>2003-01</property_0>
        <property_1>90.03</property_1>
      </Entry>
  </Overrides>
</W>
 

В настоящее время содержимое второго столбца записывается во второй узел, тогда как содержимое третьего столбца в моем CSV-файле должно быть записано (property_1 = {9001, 9002, 9003}).

Я попробовал следующее: a. Примените последовательности LINQ к матрице данных CSV без столбца даты (например, property_0) и примените мои выборки только к числовым значениям (например [[90.01, 90.02, 90.03], [9001, 9002, 9003]]. б. Используйте FileHelpers для «Игнорирования» первый столбец при сопоставлении с моим объектом класса.

В итоге я хотел бы:

 <W>
  <Overrides>
      <Entry>
        <property_0>2001-01</property_0>
        <property_1>90.01</property_1>
      </Entry>
      <Entry>
        <property_0>2002-01</property_0>
        <property_1>90.02</property_1>
      </Entry>
      <Entry>
        <property_0>2003-01</property_0>
        <property_1>90.03</property_1>
      </Entry>
  </Overrides>
</W>
<W>
  <Overrides>
      <Entry>
        <property_0>2001-01</property_0>
        <property_1>9001</property_1>
      </Entry>
      <Entry>
        <property_0>2002-01</property_0>
        <property_1>9002</property_1>
      </Entry>
      <Entry>
        <property_0>2003-01</property_0>
        <property_1>9003</property_1>
      </Entry>
  </Overrides>
</W>
 

Также будут высоко оценены любые рекомендации, связанные с рефакторингом этого набора решений. Для меня это последнее средство — и, возможно, я получу немного критики за то, что это мой первый пост без вкладов, прикрепленных к моему профилю [это правильно]. К сожалению, документация не помогает с семантикой.

Спасибо всем. Многие из нас остались бы невежественными без переполнения стека.

Ответ №1:

Обновление: вот переработанный метод для приведенных ниже фрагментов, и что в конечном итоге является более элегантным решением для исходного вопроса… Здесь начинается новый код:

 private static Schema.W[] Map(string[] headers, IEnumerable<string[]> data)
{
    Schema.W[] mapping = headers
        .Select((x, index) => new Schema.W
        {
            property_0 = x,   
            property_1 = data
                .Select((z) => new Schema.WEntry
                {
                    child_0 = z[0],
                    child_1 = z[index   1]
                }).ToArray()
        }).ToArray();
    return mapping;
}
 

Здесь начинается старый код:

 var yValues = new List<Schema.W[]>();
Schema.W[] y = null;
for (int i = 0; i < headers.Length; i  )
    {
        y = data
            .Select((z) => new Schema.W
                {
                    property_0 = z[0],
                    property_1 = decimal.Parse(z[i   1])
                }).ToArray();
                    yValues.Add(y);
                }
    }
 

И затем, наконец:

 var finalList = new List<Schema.W>();
Schema.W = null;
for (int i = 0; i < headers.Length; i  )
    {
        mapping = new Schema.W
        {
            innerNodes = yValues[i]
        };
                finalList.Add(mapping);
    }