我目前正在开展一个项目,我从电子表格中读取了行数据。基础数据的结构可以在左侧的附图中看到。还可以看出,我想分两步重新排列数据。
Image1: Steps to sort the list
PartName
组合在一起,并将两个坐标对组合在一条线上。我将coords存储在嵌套列表中。ID
组合在一起并再次组合坐标。重要的是List保持其顺序,并且最终不存在重复项。这样的事情:{x1y1,x2y2}{x2y2,x3y3}=>{x1y1,x2y2,x3y3}
。元素部分的数量是通用的,因此也是坐标对的数量。
以下是我目前正在使用的简化对象类:
public class ElmLine
{
public int Id{ get; set; }
public string PartName {get; set;}
public List<CoordList> CoordList { get; set; }
}
public class CoordList
{
public decimal XCord { get; set; }
public decimal YCord { get; set; }
}
这是我执行第1步的方法。我重新排列了基本列表,并将协调对存储在名为CoordList
的嵌套列表中。
public void BuildLinesFormSegments(IList<ElmLine> filteredLine)
{
// Merge line parts and add FROM and TO to each line part
var combinedLineParts = filteredLine
.GroupBy(c => new { c.Fid, c.FidPart }).Select(g => new ElmLine()
{
Id = g.Select(c => c.Id).First(),
PartName = g.Select(c => c.PartName).First(),
CoordList = g.Select(c => new CoordList()
{ XCord = c.CoordX, YCord = c.CoordY }).ToList(),
}).ToList();
}
结果列表combinedLineParts
如下所示:
var list = new LineParts<ElmLine>
{
new ElmLine {Name = 1, CoordList = new List<CoordList>
{new CoordList {XCord = x1, YCord = y1}, new CoordList { XCord = x2, YCord = y2 }} },
new ElmLine {Name = 1, CoordList = new List<CoordList>
{new CoordList {XCord = x2, YCord = y2}, new CoordList { XCord = x3, YCord = y3 }} },
new ElmLine {Name = 2, CoordList = new List<CoordList>
{new CoordList {XCord = x11, YCord = y11}, new CoordList { XCord = x12, YCord = y12 }} },
new ElmLine {Name = 2, CoordList = new List<CoordList>
{new CoordList {XCord = x12, YCord = y12}, new CoordList { XCord = x13, YCord = y13 }} },
};
不幸的是我在这一点上陷入困境,我不知道继续第2步。如果有人可以给我一个暗示我接下来可以做什么的话会很棒。
提前谢谢。
答案 0 :(得分:2)
第3步确实不需要依赖第2步。您只需按ID分组并保持不同的坐标值:
arr.length ===> arr["length"];
str.replace("a","") ===> str["replace"]("a","");
Element.prototype.colorize ===> Element["prototype"]["colorize"]
答案 1 :(得分:0)
经过大量的思考和StriplingWarrior的提示,我能够解决我的问题。为了完成这篇文章,我想展示一下我是如何做到的。
评论行中的### Parts ###
是对初始帖子中image1
的引用。我在这三个步骤中解决了我的问题,可以看出我在每一步中使用我的数据做了什么。
为了更好地理解我在做什么,你可以想象多米诺骨牌。每条石链由通用数量的石头组成,这些石头在基础数据中不在一条线上。
基础数据:{1,4} {1,3} {2,9} {2,7} {3,6} {3,3} {4,4} {4,7}
(每行{StoneNr,SideValue}
列表为半个石头)
第1部分的结果:[4|3] [9|7] [6|3] [4|7]
(结合了石头的清单)
第2部分的结果:[9|7] [7|4] [4|3] [3|6]
(重新排列的列表,其中所有对彼此相邻,就像多米诺链一样)
第3部分的结果:{9,7,4,3,6}
(一个包含必要顺序数字的字符串)
实际上石头值是坐标,因此数字对和石头链是2D平面中的线,但原则保持不变。
// ### Part 1 ###
var combinedLineParts = filteredLine.GroupBy(c => new { c.Fid, c.FidPart})
.Select(g => new ElmLine()
{
Fid = g.Select(c => c.Fid).First(),
FidPart = g.Select(c => c.FidPart).First(),
CoordList = g.Select(c => new CoordList()
{XCord = c.CoordX, YCord = c.CoordY}).ToList()
.GroupBy(x => new {x.XCord, x.YCord})
.Select(x => x.First()).ToList(),
}).ToList();
// ### Part 2 ###
foreach (var group in combinedLineParts.GroupBy(c => c.Fid))
{
List<List<CoordList>> coordList = group.Select(c => c.CoordList).ToList();
if (coordList.Count > 2)
{
int[] startPoint = FindStartPoint(coordList);
// if start point is not on top of the list,
// move it to the top (to: {0,0})
if (startPoint[0] > 0 || startPoint[1] > 0)
{
SwapElements(coordList, startPoint, new int[] { 0, 0 });
}
// Rearange List to sort the lineparts
int groupNumb = 0;
while (groupNumb < coordList.Count - 1)
{
RearrangeList(coordList, groupNumb);
groupNumb++;
}
}
// ### Part 3 ###
// create a new list with the sorted lineparts
combinedLines.Add( new ElmLine()
{
Fid = group.Key,
CoordList = coordList.SelectMany(d => d)
.Select(c => new {c.XCord, c.YCord})
.Distinct()
.Select(c => new CoordList()
{XCord = c.XCord, YCord = c.YCord}).ToList(),
});
}
return combinedLines;
FindStartPoint(), SwapElements(), RearrangeList()
是我自己用来解决我的特定排序问题的方法。