DATA TABLES - Is it possible to get Row Index instead of Row Name?

DataTable-Row-Index.jpg

I am using data tables and getting data by Row Name. But I name all my row names the same as the index. It would be handy if I could just get the index so I didn’t have to fill in the row names. Surprisingly no such node seems available. Am I overlooking something?

Thanks

1 Like

I looked around because this is about what I’m learning right now (data tables) and I couldn’t find an answer or anyone else asking this question.

My solution which isn’t efficient at all considering we know the index already exists -somewhere- is to create a new array and in a for loop, you can pass your data table through it to create a proper array with it. I think you’ll also have to use clear children just in case there are duplicates? I’m not too keen on the details, but I’m trying to find an answer as well. Maybe data tables aren’t really that great, I heard something called databases which may be better but I have yet to look it up.

Appreciate the response. There is a node called “Get Data Table Row Names” which outputs all the row names as a Name Array. I haven’t used it yet but it looks like that effectively lets you select row by Index assuming the Name Array is in the same order as the Data Table.

3 Likes

My solution simply is to convert integer to name (first integer to string then to name).

It’s kind of backwards since name is made of integer, but as far as finding the row goes, it isn’t any more wasteful than supplying a name in the first place.

If anyone has a better solution, I’d be intersted. Cheers

Couldn’t you get whatever column you want, return that as a string array and then run a for each loop with concern only over the array index?
See picture.

3 Likes

This here is a way to get latest items of a datatable

I know this is blueprint part but might be useful as this came up when I was searching, I ran into this in c++ here’s what I found.

Internally in data table it’s just a TMap which the documentation says isn’t guaranteed to return in a specific order if you just iterate through it.

However this obviously happens in the editor as first screen shot shows in this thread and it’s predictable.

I found this in the editor source code so it looks like you could just iterate it and say the order found is the index but I wouldn’t trust it in case it changed in the future.



// Our maps are ordered which is why we can get away with this
// If we ever change our map implementation, we'll need to preserve this order information in a separate array and
// make sure that order dependent code (such as exporting and the data table viewer) use that when dealing with rows
// This may also require making RowMap private and fixing up all the existing code that references it directly
TArray<FName> OrderedRowNames;
DataTable->GetRowMap().GenerateKeyArray(OrderedRowNames);

const int32 CurrentRowIndex = OrderedRowNames.IndexOfByKey(RowName);
if (CurrentRowIndex == INDEX_NONE)
{
return false;
}

So you can use that as a template, below is an example where I’ve done it to get an ordered copy of a data table into a TArray in the order it is in the editor, I’ve deliberately taken a copy of the struct the row is based on on purpose rather than pointers before I get told that :wink: it’s a bit hacky but works fine for a one off initial loading for small datasets.

Would be pretty easy to write a blueprint bit of code exposing that to get a TArray back in same order as the DataTable was just not something you would want to do over and over and be aware that the behaviour might change in future versions of unreal.


 if (InventoryDataTable != nullptr)
{
TArray<FName> orderedRowNames;
//generates an ordered array this is what's used in the editor display
InventoryDataTable->GetRowMap().GenerateKeyArray(orderedRowNames);

if (orderedRowNames.Num() > NumberOfSlots)
{
NumberOfSlots = orderedRowNames.Num();
}

InventoryItems.SetNum(NumberOfSlots);

FString contextString;

for (int32 i = 0; i != orderedRowNames.Num(); ++i)
{
if (InventoryItems.IsValidIndex(i))
{
//get copy of it out of the data table won't be using data table again
InventoryItems* = *(InventoryDataTable->FindRow<FInventoryItemRow>(orderedRowNames*, contextString));
}
}
}

1 Like

You can create a TMap (Index, Name) or TArray(struct).

I find that a lot of games will create a TMap (Name|Struct) or TArray (Struct) from data tables for ease of use. It’s possible to update/load data tables at run time.

putting this as a placeholder. I have done this but can’t find it now. Will update.

you ask for that?

6 Likes

This is so simple, yet, a perfect solution! Just getting an index from a table, rather than looking for a name entry. Thank you for this answer!