#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
в словаре, извлечь значение и вернуть его в aValueTuple
. - Затем используйте
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();