Получение значений из вложенного списка с помощью выражения LINQ

#c# #list #linq

Вопрос:

Я хочу записать значение _values (Freezer 01, Freezer 02, Freezer 03) из следующего вложенного списка в a List<string> , к сожалению, я понятия не имею, как это сделать.

введите описание изображения здесь

Комментарии:

1. Это связь между сущностями или Связь между объектами?

2. Что именно FluxTable и почему LINQPad предоставляет вам представление «Столбцы» и «Записи»? Я не знаком с этой библиотекой.

3. Я использую следующую библиотеку для реализации запросов к базе данных InfluxDB. github.com/influxdata/influxdb-client-csharp

Ответ №1:

Обновленный ответ:

  • Используется .SelectMany для выравнивания вложенных списков.
  • Используйте TryGetValue , чтобы одновременно проверить, "_value" существует ли запись Values в словаре, извлечь значение и вернуть его в a ValueTuple .
  • Затем используйте Where(...).Select(...) для устранения случаев, когда TryGetValue это не удалось.
  • Этот код повторяется для всех FluxTable объектов (а затем для всех FluxRecord объектов в каждой таблице). Если вы хотите выполнить итерацию только по одной таблице (что ускорит запрос Linq), сначала извлеките одну таблицу FluxTable theTable = tables.Single( /*predicater*/ ); .
    • В документации для FluxTable этого создается впечатление, что нет свойства «Имя таблицы» — это странно…
 List<FluxTable> tables = ...

List<String> values = tables
    .SelectMany( fluxTable => fluxTable.Records )
    .Select( fluxRecord => ( ok: fluxRecord.Values.TryGetValue( "_value", out String? str ), str ) )
    .Where( t => t.ok )
    .Select( t => t.str )
    .ToList();
 

Оригинальный ответ для объединенного вывода

(Я изначально неправильно истолковал ваш пост, как если бы вы спрашивали, как вы могли бы получить вывод одного String значения)

Досадно, String.Join что он не раскрывается как метод расширения для IEnumerable<String> , но если вы его определяете, это облегчает задачу…

Так что добавьте это в свой код:

 public static String StringJoin( this IEnumerable<String?> source, String separator ) 
{
    StringBuilder sb = new StringBuilder();
    foreach( String? s in source )
    {
        _ = sb.Append( s ?? String.Empty );
        _ = sb.Append( separator );
    }

    if( sb.Length > 0 ) sb.Length -= separator.Length;

    return sb.ToString();
}
 

Тогда сделай это:

 List<FluxTable> tables = ...
String allValues = tables
    .SelectMany( fluxTable => fluxTable.Records )
    .Select( fluxRecord => ( ok: fluxRecord.Values.TryGetValue( "_value", out String? str ), str ) )
    .Where( t => t.ok )
    .Select( t => t.str )
    .StringJoin( separator: ", " );

Console.WriteLine( allValues ); // "Freezer 01, Freezer 02, Freezer 03"
 

Комментарии:

1. Спасибо за ваши отзывы. Я получаю сообщение не удается преобразовать из «исходящей строки» в «выходящий объект», _value-это объект, а не строка. У вас есть еще какие-нибудь идеи, как я могу это обойти?

2. значения var = таблицы потоков . Выберите множество(fluxTable => fluxTable. Записи) . Выберите( FluxRecord => FluxRecord. GetValueByKey («_значение»)) .ТоЛист();

Ответ №2:

FluxRecord предоставляет этот метод GetValueByKey . Вот как это работало сейчас:

 var values = fluxTables.SelectMany(fluxTable => fluxTable.Records) 
                       .Select( FluxRecord => FluxRecord.GetValueByKey("_value")) 
                       .ToList();
 

https://influxdata.github.io/influxdb-client-csharp/api/InfluxDB.Client.Core.Flux.Domain.FluxRecord.html#InfluxDB_Client_Core_Flux_Domain_FluxRecord_GetValueByKey_System_String_