Merging of Two space objects into single space - c#

Here, Space is a class with (xposition, yposition, zposition, length, depth, height) as its elements and there is a list of type space.
I need to check with in the list whether it follows some conditions which are in if condition.
If it satisfies, then I merge the two spaces into single space. After that, I remove both the spaces which I have used. It actually means merging of two spaces into single space.
The new List is created. Again I treat it as new list and do the same procedure until it does not satisfies the conditions.
My problem is, it is going into infinite loop. I want to resolve this.
public class MergeSpace
{
public List<Space> Mergespace(List<Space> Listofspaces)
{
foreach (Space space1 in Listofspaces)
{
foreach (Space space2 in Listofspaces)
{
//int count = 0;
if ((space1.sheight == space2.sheight)
&& (space1.sdepth == space2.sdepth)
&& (space2.xposition == space1.xposition + space1.slength)
&& (space2.yposition == space1.yposition)
&& (space2.zposition == space1.zposition)
&& (space1.semptyspace == true)
&& (space2.semptyspace == true))
{
Space space = new Space();
space.xposition = space1.xposition;
space.yposition = space1.yposition;
space.zposition = space1.zposition;
space1.slength = space1.slength + space2.slength;
space.sheight = space1.sheight;
space.sdepth = space1.sdepth;
space.semptyspace = true;
Listofspaces.Add(space);
Listofspaces.Remove(space1);
Listofspaces.Remove(space2);
Mergespace(Listofspaces);
}

public class MergeSpace
{
public List<Space> Mergespace(List<Space> Listofspaces)
{
List<Space> mergedspacelist = new List<Space>();
int count=0;
foreach (Space space1 in Listofspaces)
{
foreach (Space space2 in Listofspaces)
{
//int count = 0;
if ((space1.sheight == space2.sheight)
&& (space1.sdepth == space2.sdepth)
&& (space2.xposition == space1.xposition + space1.slength)
&& (space2.yposition == space1.yposition)
&& (space2.zposition == space1.zposition)
&& (space1.semptyspace == true)
&& (space2.semptyspace == true))
{
Space space = new Space();
space.xposition = space1.xposition;
space.yposition = space1.yposition;
space.zposition = space1.zposition;
space1.slength = space1.slength + space2.slength;
space.sheight = space1.sheight;
space.sdepth = space1.sdepth;
space.semptyspace = true;
mergedspacelist .Add(space);
count++;
}
}
}
if(count>0)
{
Mergespace(mergedspacelist );
}
}
i dont know what your actual need is, i think this will avoid the infinite loop

Your conditions always will satisfy for same instance of Space. The instance will merge with itself.
if (!space1.Equals(space2))
{
if ((space1.sheight == space2.sheight)
...
}

Related

Clean up Validation Logic, Avoid Using Too Many If Statments

I am currently writing a validation that reads data from an api and checks for differet "domaintypes". There are 6 domaintypes types in total (windows, low, high, and dot, linux low, high, and dot) that need to present, I am currently checking by using a bunch of if statements, but I feel like it's super drawn out and messy. I've been trying to tweak it to make it more concise, but it keeps messing with the logic and I don't get what I need. I'm fairly new to c# so I'm probably missing something super obvious. Here is the current code below:
// get api response
var products = responseProvider.GetServiceResponse
var count = 0;
List<string> missingdomainskus = new List<string>();
foreach (var product in products)
{
var productInfo = responseProvider.GetProductResponse(product).Result;
var skus = productInfo.Skus;
foreach (Sku sku in skus)
{
string Name = sku.Aspects[Name];
if (sku.Aspects.ContainsKey(Item) && Item.Equals("Dot", StringComparison.OrdinalIgnoreCase) && sku.Aspects[Group].Contains("Windows"))
{
count++;
}
if (sku.Aspects.ContainsKey(Item) && Item.Equals("Low", StringComparison.OrdinalIgnoreCase) && sku.Aspects[Group].Contains("Windows"))
{
count++;
}
//Null orwhitespace = "high"
if ((!sku.Aspects.ContainsKey(Item) || string.IsNullOrWhiteSpace(Item)) && sku.Aspects[Group].Contains("Windows"))
{
count++;
}
if (sku.Aspects.ContainsKey(Item) && Item.Equals("Dot", StringComparison.OrdinalIgnoreCase) && !sku.Aspects[Group].Contains("Windows"))
{
count++;
}
if (sku.Aspects.ContainsKey(Item) && Item.Equals("Low Priority", StringComparison.OrdinalIgnoreCase) && !sku.Aspects[Group].Contains("Windows"))
{
count++;
}
if ((!sku.Aspects.ContainsKey(Item) || string.IsNullOrWhiteSpace(Item)) && !sku.Aspects[Group].Contains("Windows"))
{
count++;
}
if (count < 6)
{
missingdomainskus.Add(Name);
}
}
}
if (missingdomainskus.Any())
{
string convert = string.Join(",", missingdomainskus);
throw new CheckException($"These skus are missing domains: : {convert} i. There should be 6-7 domains per sku");
}

Paragraphs formatting slow in VSTO

I am using VSTO to get some paragraphs and save their formatting in a List.The code is working fine but the problem is that this function is taking almost 50% of the execution time of my program.
It is also known that the loop is making performance slow.
I want to know that how can I optimize the time of this function.Any alternative to list or any other thing?
public static void GetFormattedParas(Range content, Driver currentDriver)
{
// TODO add check for tables row end "\r\a" words to ignore them for query
Paragraphs paras = content.Paragraphs;
List<Paragraph> paraList = paras.Cast<Paragraph>().ToList();
List<Range> Ranges = new List<Range>();
if (paraList != null)
{
paraList.RemoveAll(range => range.Range.Text == null);
paraList.RemoveAll(range => range.Range.Text.Equals("\r\a") && range.Range.Tables.Count != 0 && range.Range.Rows[1].Range.End == range.Range.End);
for (int i = 0, ParaCount = paraList.Count; i < ParaCount; i++)
{
Range range = paraList[i].Range;
if (range.Font.Shading.BackgroundPatternColorIndex != WdColorIndex.wdNoHighlight
|| range.HighlightColorIndex != WdColorIndex.wdNoHighlight
|| range.Shading.BackgroundPatternColorIndex != WdColorIndex.wdNoHighlight)
{
Ranges.Add(paraList[i].Range);
}
}
//Ranges = (from range in paraList
// where range.Range.Font.Shading.BackgroundPatternColorIndex != WdColorIndex.wdNoHighlight
// || range.Range.HighlightColorIndex != WdColorIndex.wdNoHighlight
// || range.Range.Shading.BackgroundPatternColorIndex != WdColorIndex.wdNoHighlight
// select range.Range).OrderBy(o => o.Start).ToList();
if (Ranges != null)
{
Ranges = Ranges.OrderBy(o => o.Start).ToList();
if (Ranges.Count > 0)
{
//if (Ranges.Count == 1)
//{
// currentDriver.formattedParas.Add(content);
//}
//else
//{
currentDriver.formattedParas.AddRange(Ranges);
//}
}
}
}
}

Sum two forces with both signs

I'm trying to make a good algorithm for summing up pair of forces. The main problem here is that you can have force with alternative sign which means that force can be with + or - at any time.
For example:
F1 = ±100 kN, F2 = 200 kN --> maxForce = +100+200 = 300 kN, minForce = -100+200 = 100 kN.
I've already made an simple algorithm which combines all possibilities, but I ask for something better than that. As an output of my method I have:
public List<Force> SumForces(Force firstForce, Force secondForce)
{
Force maxForce = new Force();
Force minForce = new Force();
// All possible sumatuons
double sumCaseFirst = firstForce.ForceValue + secondForce.ForceValue;
double sumCaseSecond = firstForce.ForceValue - secondForce.ForceValue;
double sumCaseThird = -firstForce.ForceValue + secondForce.ForceValue;
double sumCaseFourth = -firstForce.ForceValue - secondForce.ForceValue;
// Calculating all posible sumations
if (firstForce.Sign == ForceSign.Alter && secondForce.Sign == ForceSign.Alter)
{
maxForce.ForceValue = sumCaseFirst;
minForce.ForceValue = sumCaseFourth;
}
else if (firstForce.Sign == ForceSign.Alter && secondForce.Sign == ForceSign.Plus)
{
maxForce.ForceValue = sumCaseFirst;
minForce.ForceValue = sumCaseThird;
}
else if (firstForce.Sign == ForceSign.Alter && secondForce.Sign == ForceSign.Minus)
{
maxForce.ForceValue = sumCaseSecond;
minForce.ForceValue = sumCaseFourth;
}
else if (firstForce.Sign == ForceSign.Plus && secondForce.Sign == ForceSign.Alter)
{
maxForce.ForceValue = sumCaseFirst;
minForce.ForceValue = sumCaseSecond;
}
else if (firstForce.Sign == ForceSign.Plus && secondForce.Sign == ForceSign.Plus)
{
maxForce.ForceValue = sumCaseFirst;
minForce.ForceValue = 0;
}
else if (firstForce.Sign == ForceSign.Plus && secondForce.Sign == ForceSign.Minus)
{
maxForce.ForceValue = sumCaseSecond;
minForce.ForceValue = 0;
}
else if (firstForce.Sign == ForceSign.Minus && secondForce.Sign == ForceSign.Alter)
{
maxForce.ForceValue = sumCaseThird;
minForce.ForceValue = sumCaseFourth;
}
else if (firstForce.Sign == ForceSign.Minus && secondForce.Sign == ForceSign.Plus)
{
maxForce.ForceValue = sumCaseThird;
minForce.ForceValue = 0;
}
else
{
maxForce.ForceValue = 0;
minForce.ForceValue = sumCaseFourth;
}
// Ensure that true maximum force value is at index 0
if (maxForce.ForceValue > minForce.ForceValue)
{
Sum.Add(maxForce);
Sum.Add(minForce);
}
else
{
Sum.Add(minForce);
Sum.Add(maxForce);
}
return Sum;
}
The maximum is always when adding the positive values
double maxValue = Math.Abs(firstForce.ForceValue) + Math.Abs(secondForce.ForceValue);
The minimum is always when adding the negative values
double minValue = -Math.Abs(firstForce.ForceValue) - Math.Abs(secondForce.ForceValue);
There is no need to consider the positive and negative combinations.

how to iterate collection and change value

I know this is a dumb question because you cannot modify the loop collection while in a loop, but I do need to change it. I know I must not change the referenced objects, but I have no idea how to do this.
var orders = _orderService.GetOrders(o => !o.Deleted &&
o.OrderStatus != OrderStatus.Cancelled &&
o.OrderStatus != OrderStatus.Complete);
foreach (var order in orders)
{
if (order.PaymentStatus == PaymentStatus.Paid)
{
if (order.ShippingStatus == ShippingStatus.ShippingNotRequired || order.ShippingStatus == ShippingStatus.Delivered)
{
var tempOrder = _orderService.GetOrderById(order.Id);
SetOrderStatus(tempOrder , OrderStatus.Complete, true);
}
}
}
I always get an error.
UPDATED: I changed to this
var orders = _orderService.GetOrders(o => !o.Deleted &&
o.OrderStatus != OrderStatus.Cancelled && o.OrderStatus != OrderStatus.CompletE);
List<int> orderIndex = new List<int>();
orders.ToList().ForEach(x => orderIndex.Add(x.Id));
foreach(var index in orderIndex)
{
var order = _orderService.GetOrderById(index);
if (order.PaymentStatus == PaymentStatus.Paid)
{
if (order.ShippingStatus == ShippingStatus.ShippingNotRequired || order.ShippingStatus == ShippingStatus.Delivered)
{
SetOrderStatus(order, OrderStatus.Complete, true);
}
}
}
try
int count = orders.Count; // the length of the collect : may need a different method for different collection types.
for(int i = 0; i < count; i++)
{
var current = orders[i];
// do stuff with current.
}
use for loop instead of foreach loop
for(int i=0; i<orders.Count; i++)
{
if (orders[i].PaymentStatus == PaymentStatus.Paid)
{
if (orders[i].ShippingStatus == ShippingStatus.ShippingNotRequired || orders[i].ShippingStatus == ShippingStatus.Delivered)
{
var tempOrder = _orderService.GetOrderById(orders[i].Id);
SetOrderStatus(tempOrder , OrderStatus.Complete, true);
}
}
}

More Efficient Way To Split a Balanced String C#

I've done this with balancing Regex's before when I only had one balancing character...but with more balancing characters it gets more complicated and uglier.
For my current purpose, I instead wrote an method to do this by tokenizing the string but it's terribly slow (and terribly inefficient) The most expensive part seems to be the gratuitous Substring usage I'm doing (yeah I know it's bad).
Basically, I want to take the following
hello("(abc d)", efg (hijk)) and,some more<%lmn, "o(\")pq", (xy(z))%>
and end up with
hello("(abc d)", efg (hijk))
[space] (the actual character)
and
,
some more
<%lmn, "o()pq", (xy(z))%>
In other words, I'm splitting on (and I want these included in the array results)
[space]
,
....and I have "balanced grouping strings"
" "
( )
<% %>
...and I have escape characters
\
I'd prefer not to write a whole big parser for this purpose...
Here's the code:
public static IEnumerable<string> SplitNotEnclosed(this string s, IEnumerable<string> separators, Dictionary<string, string> enclosingValues = null, IEnumerable<char> escapeCharacters = null, bool includeSeparators = false, StringComparison comparisonType = StringComparison.Ordinal)
{
var results = new List<string>();
var enclosureStack = new Stack<KeyValuePair<string, string>>();
bool atEscapedCharacter = false;
if (escapeCharacters == null) escapeCharacters = new[] { '\\' };
if (enclosingValues == null) enclosingValues = new[] { "\"" }.ToDictionary(i => i);
var orderedEnclosingValues = enclosingValues.OrderByDescending(i => i.Key.Length).ToArray();
separators = separators.OrderByDescending(v => v.Length).ToArray();
var currentPart = new StringBuilder();
while (s.Length > 0)
{
int addToIndex = 0;
var newEnclosingValue = orderedEnclosingValues.FirstOrDefault(v => s.StartsWith(v.Key, comparisonType));
if (enclosureStack.Count > 0 && !atEscapedCharacter && s.StartsWith(enclosureStack.Peek().Value))
{
addToIndex = enclosureStack.Peek().Value.Length;
enclosureStack.Pop();
}
else if (newEnclosingValue.Key != null && !atEscapedCharacter)
{
enclosureStack.Push(newEnclosingValue);
addToIndex = newEnclosingValue.Key.Length;
}
else if (escapeCharacters.Contains(s[0]) && enclosureStack.Count > 0)
{
atEscapedCharacter = !atEscapedCharacter;
addToIndex = 1;
}
else if (enclosureStack.Count > 0)
{
atEscapedCharacter = false;
addToIndex = 1;
}
if (enclosureStack.Count == 0)
{
string separator = separators.FirstOrDefault(v => s.StartsWith(v, comparisonType));
if (separator != null)
{
if (currentPart.Length > 0) results.Add(currentPart.ToString());
results.Add(separator);
s = s.Substring(separator.Length);
currentPart = new StringBuilder();
addToIndex = 0;
}
else
{
addToIndex = 1;
}
}
currentPart.Append(s.Substring(0, addToIndex));
s = s.Substring(addToIndex);
}
if (currentPart.Length > 0) results.Add(currentPart.ToString());
if (!includeSeparators)
{
results = results.Except(separators).ToList();
}
return results.ToArray();
}

Categories

Resources