Reputation: 4811
I have a model like below
public class PropsModel
{
public int props_id { get; set; }
public string props_name { get; set; }
public int props_order { get; set; }
}
Sample values
[
{ 1, "red" ,0 }
{ 2, "green", 3}
{ 1, "light red" ,1 }
{ 3, "yellow", 2}
{ 2, "blue", 6}
]
Result STRING : "red/light red" , "yellow" , "green/blue"
Output string rules
Current implementation
List<string> _inflections = new List<string>();
var distinctIDs = inflections_model.Select(x => x.form_id).Distinct(); //find distinct IDs
foreach (int _id in distinctIDs) //for each distinct ID , join the string to LIST
{
string inflection_val = string.Join(" / ", from item in inflections_model
where item.form_id==_id
select item.props_name );
_inflections.Add(inflection_val);
}
string inflection_string = string.Join(", ", _inflections); //combine processed STRINGS to a comma separate list
This produces needed result , but not in the order (props_order is not used anywhere).
Can we make this to a single LINQ query?
Upvotes: 0
Views: 562
Reputation: 1416
var list = models.OrderBy(x => x.props_order).ToLookup(x => x.props_id, x => x.props_name).Select(name => string.Join("/", name));
var result = string.Join(",", list);
Prints
"red/light red,yellow,green/blue"
Better performance with Lookup
On machine,
GroupBy => takes 1.6215 milliseconds
Lookup => takes 0.2072 milliseconds
Upvotes: 1
Reputation: 16089
You can try below implementation
var groups = list.GroupBy(x => x.props_id); //Group By Id
List<string> stringList = new List<string>(); //stringList to store common records with /
foreach(var grp in groups)
stringList.Add(string.Join("/", list.Where(x => x.props_id == grp.Key).Select(y => y.props_name))); //Logic to select property names from common groups
Console.WriteLine(string.Join(", ", stringList)); //Print result
Output:
red/light red, green/blue, Yellow
Upvotes: 2
Reputation: 2134
You may use LINQ GroupBy and Select:
var data = inflections_model.GroupBy(p=> p.props_id) // this gives you groups
.Select(g =>
String.Join("/", g.OrderBy(r=>r.props_order)
.Select(r=>r.props_name)))
var inflection_string = string.Join(", ",data)
Upvotes: 2
Reputation: 5380
You need to GroupBy
items props_id and OrderBy
props_order as following one single LINQ:
var _inflections = inflections_model.OrderBy(o => o.props_order)
.GroupBy(i => i.props_id)
.Select(s => String.Join("/", s.Select(p => p.props_name)));
var inflection_string = String.Join(",", _inflections);
It will give following result as desired:
"red/light red","yellow","green/blue"
Upvotes: 2
Reputation: 488
This orders the groups of elements based on the lowest value of props_order
in each group
string.Join(", ",
inflections_model
.GroupBy(o => o.props_id)
.OrderBy(g => g.Min(o => o.props_order))
.Select(g => string.Join("/", g.Select(o => o.props_name))));
Upvotes: 2