Home > Enterprise >  Get values from a nested list with a LINQ expression
Get values from a nested list with a LINQ expression

Time:09-17

I want to write the value _values (Freezer 01, Freezer 02, Freezer 03) from the following nested list into a List<string>, unfortunately I have no idea how to accomplish this.

enter image description here

CodePudding user response:

Updated answer:

  • Use .SelectMany to flatten nested lists.
  • Use TryGetValue to simultaneously check if "_value" exists in a record's Values dictionary and to extract the value and return it in a ValueTuple.
  • Then use Where(...).Select(...) to eliminate cases where TryGetValue failed.
  • This code iterates over all FluxTable objects (and then over all FluxRecord objects in each table). If you only want to iterate over a single table (which will make the Linq query faster) then first extract the single table with FluxTable theTable = tables.Single( /*predicater*/ );.
    • The documentation for FluxTable makes it seem like there's no "Table name" property - that's weird...
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();

Original answer for concatenated output

(I originally misread your post as if you were asking how you could get the output to a single String value)

Annoyingly, String.Join is not exposed as an extension-method for IEnumerable<String>, but if you do define it it makes things easier...

So add this to your code:

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();
}

Then do this:

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"

CodePudding user response:

FluxRecord provides the method GetValueByKey. This is how it worked now:

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_

  • Related