在单个 foreach C# 中迭代 2 个形状列表
Iterate through 2 lists of shapes within a single foreach C#
我有 2 个来自 2 个单独的 PowerPoint 演示文稿的 shapeId 列表,一个来自原始 PowerPoint,另一个来自编辑过的 PowerPoint。
我现在想比较这两个 ShapeId 列表中的项目。例如我想比较颜色和字体大小等。
我尝试了多种方法来执行此操作,并决定最好的方法是遍历 2 个列表中的每个 ShapeId。无论如何我可以在一个 foreach 循环中遍历每个列表吗?比如foreach (Microsoft.Office.Interop.PowerPoint.Slide slide item1 in list1, Microsoft.Office.Interop.PowerPoint.Slide slide item2 in list2)
我的代码是休闲的
Microsoft.Office.Interop.PowerPoint.CustomLayout customLayout = pptPresentationOriginal.SlideMaster.CustomLayouts[Microsoft.Office.Interop.PowerPoint.PpSlideLayout.ppLayoutText];
Microsoft.Office.Interop.PowerPoint.Slides Originalslides;
Microsoft.Office.Interop.PowerPoint.Slides EditedSlides;
Microsoft.Office.Interop.PowerPoint.Shape originalShp;
Microsoft.Office.Interop.PowerPoint.Shape editShp;
Originalslides = pptPresentationOriginal.Slides;
EditedSlides = pptPresentationEdit.Slides;
List<char> l = new List<char>();
List<char> l2 = new List<char>();
List<int> originalShapesListID = new List<int>();
List<int> editedShapesListID = new List<int>();
List<int> originalListID = new List<int>();
List<int> editedListID = new List<int>();
List<Microsoft.Office.Interop.PowerPoint.Shape> originalList = new List<Microsoft.Office.Interop.PowerPoint.Shape>();
List<Microsoft.Office.Interop.PowerPoint.Shape> editList = new List<Microsoft.Office.Interop.PowerPoint.Shape>();
Microsoft.Office.Interop.PowerPoint.Shape editedShpID;
逻辑
String pps = "";
foreach (Microsoft.Office.Interop.PowerPoint.Slide slide in Originalslides)
{
foreach (Microsoft.Office.Interop.PowerPoint.Shape originalShape in slide.Shapes)
{
originalShp = originalShape;
if (originalShape.HasTextFrame == Microsoft.Office.Core.MsoTriState.msoTrue)
{
var textFrame = originalShape.TextFrame;
if (textFrame.HasText == Microsoft.Office.Core.MsoTriState.msoTrue)
{
var textRange = textFrame.TextRange;
pps += originalShape.TextFrame.TextRange.Text;
foreach (char word in pps)
{
l.Add(word);
Debug.WriteLine(word);
}
}
}
originalShapesListID.Add(originalShape.Id);
originalShapeID = originalShape.Id;
originalList.Add(originalShape);
}
originalListID.Add(slide.SlideID);
}
foreach (Microsoft.Office.Interop.PowerPoint.Slide slide in EditedSlides)
{
foreach (Microsoft.Office.Interop.PowerPoint.Shape editShape in slide.Shapes)
{
editShp = editShape;
if (editShape.HasTextFrame == Microsoft.Office.Core.MsoTriState.msoTrue)
{
var textFrame = editShape.TextFrame;
if (textFrame.HasText == Microsoft.Office.Core.MsoTriState.msoTrue)
{
var textRange = textFrame.TextRange;
pps += editShape.TextFrame.TextRange.Text;
foreach (char word in pps)
{
l.Add(word);
Debug.WriteLine(word);
}
}
}
editedShapesListID.Add(editShape.Id);
editedShapeID = editShape.Id;
editList.Add(editShape);
}
editedListID.Add(slide.SlideID);
}
这里是我要浏览 2 个列表并比较每个列表中的每个项目 (ShapeId) 的地方。我想做这样的事情。
foreach (Microsoft.Office.Interop.PowerPoint.Shape editShape in editedShapesListID, Microsoft.Office.Interop.PowerPoint.Shape original in originalShapesListID )
{
if (originalShapeID == editedShapeID)
{
if (original.TextFrame.TextRange.Font.Color.RGB != editShape.TextFrame.TextRange.Font.Color.RGB)
{
originalShp.TextFrame2.TextRange.Font.StrikeThrough.ToString();
}
}
}
using (var originalEnumerator = originalShapesListID.GetEnumerator())
foreach (var editShape in editedShapesListID)
{
if (!originalEnumerator.MoveNext()) break;
var original = originalEnumerator.Current;
...
}
您可以使用 2 个字典而不是 4 个列表,然后使用 Join
。
这是一个使用 int 和字符串的示例(针对您的问题,将字符串替换为 Microsoft.Office.Interop.PowerPoint.Shape):
Dictionary<int, string> loDicOriginal = new Dictionary<int, string>();
Dictionary<int, string> loDicEdit = new Dictionary<int, string>();
loDicOriginal.Add(1, "int 1 list 1");
loDicOriginal.Add(2, "int 2 list 1");
loDicOriginal.Add(3, "int 3 list 1");
loDicEdit.Add(1, "int 1 list 2");
loDicEdit.Add(3, "int 3 list 2");
var loQuery = loDicOriginal.Join(loDicEdit,
dicOrg => dicOrg.Key,
dicEdit => dicEdit.Key,
(entryOrg, entryEdit) => new { Original = entryOrg, Edit = entryEdit });
foreach (var loOut in loQuery)
{
System.Diagnostics.Debug.WriteLine("{0}->{1} | {2}->{3}", loOut.Original.Key, loOut.Original.Value, loOut.Edit.Key, loOut.Edit.Value);
}
输出为:
1->int 1 list 1 | 1->int 1 list 2
3->int 3 list 1 | 3->int 3 list 2
希望大家明白我的意思。
因为您想匹配特定键上的项目 Id
。一个好的选择是使用 join
。 Join 将为具有 O(1) 查找的内部集合构建一个 hash-table。
var q = from original in originalShapes
join editedTmp in editedShapes on original.Id equals editedTmp.Id into g
from edited in g.DefaultIfEmpty()
select new
{
original,
edited
};
foreach(var item in q)
{
//item.edited might be null if no matching original was found.
if (item.edited == null || item.original.TextFrame.TextRange.Font.Color.RGB != item.edited.TextFrame.TextRange.Font.Color.RGB)
{
item.original.TextFrame2.TextRange.Font.StrikeThrough.ToString();
}
}
我有 2 个来自 2 个单独的 PowerPoint 演示文稿的 shapeId 列表,一个来自原始 PowerPoint,另一个来自编辑过的 PowerPoint。
我现在想比较这两个 ShapeId 列表中的项目。例如我想比较颜色和字体大小等。
我尝试了多种方法来执行此操作,并决定最好的方法是遍历 2 个列表中的每个 ShapeId。无论如何我可以在一个 foreach 循环中遍历每个列表吗?比如foreach (Microsoft.Office.Interop.PowerPoint.Slide slide item1 in list1, Microsoft.Office.Interop.PowerPoint.Slide slide item2 in list2)
我的代码是休闲的
Microsoft.Office.Interop.PowerPoint.CustomLayout customLayout = pptPresentationOriginal.SlideMaster.CustomLayouts[Microsoft.Office.Interop.PowerPoint.PpSlideLayout.ppLayoutText];
Microsoft.Office.Interop.PowerPoint.Slides Originalslides;
Microsoft.Office.Interop.PowerPoint.Slides EditedSlides;
Microsoft.Office.Interop.PowerPoint.Shape originalShp;
Microsoft.Office.Interop.PowerPoint.Shape editShp;
Originalslides = pptPresentationOriginal.Slides;
EditedSlides = pptPresentationEdit.Slides;
List<char> l = new List<char>();
List<char> l2 = new List<char>();
List<int> originalShapesListID = new List<int>();
List<int> editedShapesListID = new List<int>();
List<int> originalListID = new List<int>();
List<int> editedListID = new List<int>();
List<Microsoft.Office.Interop.PowerPoint.Shape> originalList = new List<Microsoft.Office.Interop.PowerPoint.Shape>();
List<Microsoft.Office.Interop.PowerPoint.Shape> editList = new List<Microsoft.Office.Interop.PowerPoint.Shape>();
Microsoft.Office.Interop.PowerPoint.Shape editedShpID;
逻辑
String pps = "";
foreach (Microsoft.Office.Interop.PowerPoint.Slide slide in Originalslides)
{
foreach (Microsoft.Office.Interop.PowerPoint.Shape originalShape in slide.Shapes)
{
originalShp = originalShape;
if (originalShape.HasTextFrame == Microsoft.Office.Core.MsoTriState.msoTrue)
{
var textFrame = originalShape.TextFrame;
if (textFrame.HasText == Microsoft.Office.Core.MsoTriState.msoTrue)
{
var textRange = textFrame.TextRange;
pps += originalShape.TextFrame.TextRange.Text;
foreach (char word in pps)
{
l.Add(word);
Debug.WriteLine(word);
}
}
}
originalShapesListID.Add(originalShape.Id);
originalShapeID = originalShape.Id;
originalList.Add(originalShape);
}
originalListID.Add(slide.SlideID);
}
foreach (Microsoft.Office.Interop.PowerPoint.Slide slide in EditedSlides)
{
foreach (Microsoft.Office.Interop.PowerPoint.Shape editShape in slide.Shapes)
{
editShp = editShape;
if (editShape.HasTextFrame == Microsoft.Office.Core.MsoTriState.msoTrue)
{
var textFrame = editShape.TextFrame;
if (textFrame.HasText == Microsoft.Office.Core.MsoTriState.msoTrue)
{
var textRange = textFrame.TextRange;
pps += editShape.TextFrame.TextRange.Text;
foreach (char word in pps)
{
l.Add(word);
Debug.WriteLine(word);
}
}
}
editedShapesListID.Add(editShape.Id);
editedShapeID = editShape.Id;
editList.Add(editShape);
}
editedListID.Add(slide.SlideID);
}
这里是我要浏览 2 个列表并比较每个列表中的每个项目 (ShapeId) 的地方。我想做这样的事情。
foreach (Microsoft.Office.Interop.PowerPoint.Shape editShape in editedShapesListID, Microsoft.Office.Interop.PowerPoint.Shape original in originalShapesListID )
{
if (originalShapeID == editedShapeID)
{
if (original.TextFrame.TextRange.Font.Color.RGB != editShape.TextFrame.TextRange.Font.Color.RGB)
{
originalShp.TextFrame2.TextRange.Font.StrikeThrough.ToString();
}
}
}
using (var originalEnumerator = originalShapesListID.GetEnumerator())
foreach (var editShape in editedShapesListID)
{
if (!originalEnumerator.MoveNext()) break;
var original = originalEnumerator.Current;
...
}
您可以使用 2 个字典而不是 4 个列表,然后使用 Join
。
这是一个使用 int 和字符串的示例(针对您的问题,将字符串替换为 Microsoft.Office.Interop.PowerPoint.Shape):
Dictionary<int, string> loDicOriginal = new Dictionary<int, string>();
Dictionary<int, string> loDicEdit = new Dictionary<int, string>();
loDicOriginal.Add(1, "int 1 list 1");
loDicOriginal.Add(2, "int 2 list 1");
loDicOriginal.Add(3, "int 3 list 1");
loDicEdit.Add(1, "int 1 list 2");
loDicEdit.Add(3, "int 3 list 2");
var loQuery = loDicOriginal.Join(loDicEdit,
dicOrg => dicOrg.Key,
dicEdit => dicEdit.Key,
(entryOrg, entryEdit) => new { Original = entryOrg, Edit = entryEdit });
foreach (var loOut in loQuery)
{
System.Diagnostics.Debug.WriteLine("{0}->{1} | {2}->{3}", loOut.Original.Key, loOut.Original.Value, loOut.Edit.Key, loOut.Edit.Value);
}
输出为:
1->int 1 list 1 | 1->int 1 list 2
3->int 3 list 1 | 3->int 3 list 2
希望大家明白我的意思。
因为您想匹配特定键上的项目 Id
。一个好的选择是使用 join
。 Join 将为具有 O(1) 查找的内部集合构建一个 hash-table。
var q = from original in originalShapes
join editedTmp in editedShapes on original.Id equals editedTmp.Id into g
from edited in g.DefaultIfEmpty()
select new
{
original,
edited
};
foreach(var item in q)
{
//item.edited might be null if no matching original was found.
if (item.edited == null || item.original.TextFrame.TextRange.Font.Color.RGB != item.edited.TextFrame.TextRange.Font.Color.RGB)
{
item.original.TextFrame2.TextRange.Font.StrikeThrough.ToString();
}
}