Reputation: 766
I have this class
public class Line
{
public string ConnectionsIndex{get;set;}
}
my Linq problem is that I have to aggregate these Lines
var l1 = new Line{ ConnectionsIndex="01,02"};
var l2 = new Line{ ConnectionsIndex="02,03"};
var l3 = new Line{ ConnectionsIndex="01,03"};
into this
var l4 = new Line{ ConnectionsIndex="01,02,03"};
It's possible to do with Linq?
DETAIL:
The thing is more complicate (at least for me) when I add the other items that I have in my collection.
var l5 = new Line (ConnectionsIndex = "02,04");
var l6 = new Line (ConnectionsIndex = "03,06");
because do not exist other lines with the pairs 03,04 , 01,04 , 01,06 and 02,06
I do not know if I have explained it well ...
in practice, imagine you have all the points of a polygon, I want to get a line of all the items from the query by giving a list of connections between all points of each polygon.
(my list contains more than one polygon)
One point should not be included in result if not connected to all others.
This is an example of my list content:
ConnectionsIndex="166,171"
ConnectionsIndex="166,174"
ConnectionsIndex="166,333"
ConnectionsIndex="169,170"
ConnectionsIndex="171,175"
ConnectionsIndex="171,334"
ConnectionsIndex="167,174"
ConnectionsIndex="172,174"
ConnectionsIndex="174,335"
ConnectionsIndex="177,341"
ConnectionsIndex="180,200"
ConnectionsIndex="181,183"
ConnectionsIndex="182,199"
ConnectionsIndex="184,185"
ConnectionsIndex="186,188"
ConnectionsIndex="189,192"
ConnectionsIndex="190,230"
ConnectionsIndex="191,375"
In this List you have for example a triangle between 166, 171 and 334
More detail:
var group = lines.Where(x => x.ConnectionsIndex.Split(',').Contains(line. ConnectionsIndex.Split(',')[0]) || x. ConnectionsIndex.Split(',').Contains(line. ConnectionsIndex.Split(',')[1])).ToList(); if (group.Count()==1) { straight_lines.Add(line); } else { //Here I have a "group" with all the lines between point.. I want to get distinc points }
Upvotes: 0
Views: 427
Reputation: 3325
Just a note that I think what you're asking for is a way to find maximal cliques (a concept from graph theory). This is known to be an NP-Hard problem. I think your version will work sometimes, and hopeflly for those cases you're interested in. But, not for complicated cases where anything may be connected to anything else. Indeed, if you have a lot of nodes, those cases aren't feasible, even with large CPU cycle budgets (regardless of LINQ).
Upvotes: 0
Reputation: 766
This is the bad way I have found... and it works!
var l = linee.Distinct(
(a, b) => a.ConnectionsIndex == b.ConnectionsIndex,x=>x.ConnectionsIndex.GetHashCode())
.ToList();
var single_lines = new List<Linea>();
var multiple_lines = new List<Linea>();
foreach (var linea in l)
{
var group = l
.Where(x => x.ConnectionsIndex.Split(',').Contains(linea.ConnectionsIndex.Split(',')[0]) ||
x.ConnectionsIndex.Split(',').Contains(linea.ConnectionsIndex.Split(',')[1])).ToList();
if (group.Count()==1)
{
single_lines.Add(linea);
}
else
{
var indexes = new List<string>();
var dist = group.Select(x => new {Index = x.ConnectionsIndex.Split(',').ToList()}).ToList();
foreach (var linea1 in dist)
{
indexes=indexes.Concat(linea1.Index).ToList();
}
var indexstring = new StringBuilder();
foreach (var s in indexes.Distinct().OrderBy(x=>Convert.ToInt32(x)))
{
indexstring.Append(s).Append(',');
}
indexstring.Remove(indexstring.Length - 1, 1);
multiple_lines.Add(new Linea() {ConnectionsIndex = indexstring.ToString()});
}
}
var multi_distinct=multiple_lines.Distinct(
(a, b) => a.ConnectionsIndex == b.ConnectionsIndex, x => x.ConnectionsIndex.GetHashCode())
.ToList();
linee = single_lines.Concat(multi_distinct).ToList();
If you find or known better solutions, you are welcome!
Upvotes: 0
Reputation: 39650
I used this:
var l4 = new Line{
ConnectionsIndex =
string.Join(",", (lines.SelectMany(x => x.ConnectionsIndex.Split(','))
.Distinct()
.OrderBy(s => s)).ToArray())
};
Upvotes: 0
Reputation: 1503439
Something like:
var connections = (from line in lines
from connection in line.Split(',')
select connection).Distinct()
.ToArray();
Line line = new Line { ConnectionsIndex = string.Join(",", connections) };
This doesn't order the connections, but you can easily add that if you need it.
This would all be cleaner if you were happy to have ConnectionsIndex
as a collection of strings instead of a single delimited string, of course :)
Upvotes: 1