I’ve got a data structure Dictionary<int, float[]>
and I want to generate a float[] which is the nth entry from each float[]. I can do this in code:
float[] rowData = new float[rawData.Count];
for (int row = 0; row < numRows; row++)
{
int col = 0;
foreach (var key in keys)
rowData[col++] = rawData[key][row];
Is there a clever way to do this using Linq so I don’t need the “foreach”?
3
I think what you’re looking for is a simple select
:
var nthRow = 1; // or whatever n is
var rowData = rawData.Select(kvp => kvp.Value[nthRow]).ToArray();
Please note that nthRow
must be inside the bounds of the smallest array in the dictionary, otherwise you’ll get an IndexOutOfRangeException
.
The following code will produce a float[]
with the values [0.2, 1.2, 2.2]
*:
Dictionary<int, float[]> rawData = new () {
{1, [0.0f, 0.1f, 0.2f, 0.3f]},
{2, [1.0f, 1.1f, 1.2f, 1.3f]},
{3, [2.0f, 2.1f, 2.2f, 2.3f]},
};
var nthRow = 2;
var rowData = rawData.Select(kvp => kvp.Value[nthRow]).ToArray();
*Please note, however, that a Dictionary<TKey, TValue>
is an unordered collection, where the only guarantee for order is that an iteration of its Keys
will always be in the same order as an iteration of its Values
– so the order of the values inside the final float[]
array is not guaranteed.
Let’s state the problem:
Given
n >= 0
andrawData
dictionary, we want to obtainn
th item fromValues
when it exists
If it’s your task then Linq can be
var rowData = rawData
.Values // Values, i.e. arrays
.Where(array => array.Length > n) // Which have at least n items
.Select(array => array[n]) // Take n-th item
.ToArray(); // Materialize as array
If you want to provide some defaultItem
if array is too short:
var rowData = rawData
.Values
.Select(array => array.Length >= n ? array[n] : defaultItem)
.ToArray();