Conditional selection in LINQ (select instead if empty)

Is there any way "LINQ" to have conditional data selection, i.e. choose from another source if the first one was empty? For example, if you have a tree-like structure of elements, and you want to get some asset from the root, or if it is empty, there will be children from it.

I have the following example:

IEnumerable<Item> items = ...; // Item has a Assets property that returns IEnumerable<Asset> // Item has a SubItems property that returns IEnumerable<Item> // ie other items with assets in them // getting assets from a "main" item var assets = item.Assets.Where(a => HasRelevantAsset(a)); // if there were no relevant assets in the "main" item if (!assets.Any()) { // then reselect from "subitems" assets instead assets = item.SubItems.SelectMany(item => item.Assets.Where(a => HasRelevantAsset(a))); } // HasRelevantAsset(Asset) is a static method that returns // true if it is the asset that is needed 
+6
source share
1 answer

I find the LINQ way will look a little ugly

 var assets = item.Any(a=>HaRelevantAsset(a)) ? item.Where(a => HasRelevantAsset(a)) : item.SubItems.SelectMany(item => item.Assets.Where(a => HasRelevantAsset(a))); 

I would choose another option, the extension method

 public static IEnumerable<Asset> SelectRelevantAssets(this Item item) { var assetsInItemFound = false; foreach (var asset in item.Assets) { if (HasRelevantAsset(asset)) { assetsInItemFound = true; yield return asset; } } if (assetsInItemFound) { yield break; } else { foreach (var subItem in item.SubItems) foreach (var asset in subItem.Assets) if (HasRelevantAsset(asset)) yield return asset; } } 







At first I wanted to try the recursive call to SelectRelevantAssets, I think it would be like

 if (!assetsInItemFound) { yield break; } else { foreach (var subItem in item.SubItems) foreach (var asset in SelectRelevantAssets(subItem)) yield return asset; } 

But this will include the assets found in the Items collection of subItem elements

+1
source

Source: https://habr.com/ru/post/912301/


All Articles