Rearrange string collections in C #

It looks like I'm stuck again with recursive algorithms ...

My application should sort the files in different folders in accordance with the information specified by the user and in accordance with the structure of the subfolder represented by a line similar to the following:

[ROOT] \ brand \ color \ material \ 

Tags in a string string represent collections:

Suppose:

 var brand = new List<string> { "Nike", "Adidas", "Reebok" }; var color = new List<string> { "red", "blue", "yellow", "black" }; var material = new List<string> { "leather", "fabric" }; var data = new List<List<string>>() { brand, color, material }; 

And what I'm trying to get is something like:

 [ROOT]\Nike\red\leather [ROOT]\Nike\red\fabric [ROOT]\Nike\blue\leather [ROOT]\Nike\blue\fabric [ROOT]\Nike\yellow\leather [ROOT]\Nike\yellow\fabric [ROOT]\Nike\black\leather [ROOT]\Nike\black\fabric [ROOT]\Adidas\red\leather [ROOT]\Adidas\red\fabric [ROOT]\Adidas\blue\leather [ROOT]\Adidas\blue\fabric [ROOT]\Adidas\yellow\leather [ROOT]\Adidas\yellow\fabric [ROOT]\Adidas\black\leather [ROOT]\Adidas\black\fabric [ROOT]\Reebok\red\leather [ROOT]\Reebok\red\fabric [ROOT]\Reebok\blue\leather [ROOT]\Reebok\blue\fabric [ROOT]\Reebok\yellow\leather [ROOT]\Reebok\yellow\fabric [ROOT]\Reebok\black\leather [ROOT]\Reebok\black\fabric 

The problem is that the number of data tags (brand, color, material) and their order are not known in advance, therefore, the need for recursion.

Any idea?

Thank you so much in advance!

+1
source share
2 answers

Here is Eric Lippert's code. Cartesian product.

http://ericlippert.com/2010/06/28/computing-a-cartesian-product-with-linq/

 public static IEnumerable<IEnumerable<T>> CartesianProduct<T>(this IEnumerable<IEnumerable<T>> sequences) { // base case: IEnumerable<IEnumerable<T>> result = new[] { Enumerable.Empty<T>() }; foreach (var sequence in sequences) { var s = sequence; // don't close over the loop variable // recursive case: use SelectMany to build the new product out of the old one result = from seq in result from item in s select seq.Concat(new[] { item }); } return result; } 

 var result = CartesianProduct(new List<List<string>>() {brand,color,material }); 

Usage example:

 var brand = new List<string> { "Nike", "Adidas", "Reebok" }; var color = new List<string> { "red", "blue", "yellow", "black" }; var material = new List<string> { "leather", "fabric" }; foreach (var row in CartesianProduct(new List<List<string>>() { brand, color, material })) { Console.WriteLine(String.Join(",", row)); } 
+8
source

Here is an easy way, connecting the current result with each member of the next. To do this, you also need to create any array containing [ROOT].

  var root = new List<string> { "[ROOT]" }; var brand = new List<string> { "Nike", "Adidas", "Reebok" }; var color = new List<string> { "red", "blue", "yellow", "black" }; var material = new List<string> { "leather", "fabric" }; var data = new List<List<string>>() { root, brand, color, material }; IEnumerable<string> lstComb = new List<string> { null }; foreach (var list in data) { lstComb = lstComb.SelectMany(o => list.Select(s => $"{o}\\{s}".TrimStart(new char[]{'\\'}))); } 

Note. When adding items to a data list containing lists, the order must be preserved.

0
source

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


All Articles