JSON serializing of objects with huge IEnumerable is very slow - c#

I would like to serialize the Result object into JSON but it takes a lot of time, like more than 1 minute when the whole process just take 1.5 seconds without the serializing part.
I have tried using Json.NET and fastJSON but both with the same slowness.
IEnumerable<IEnumerable<int>> geometry in ResultFeature can be really huge as it can contains dozens of thousands of integers.
Why does it takes that long?
using System;
using System.Collections.Generic;
using fastJSON;
using ESRI.ArcGIS.ADF;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.esriSystem;
namespace DesktopConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var watch = System.Diagnostics.Stopwatch.StartNew();
Result result = new Result
{
fields = new List<string>
{
"CD_MUNCP",
"NOM_MUNCP"
},
features = CreateResultFeatures().ToList()
};
string json = JSON.ToJSON(result);
watch.Stop();
Console.WriteLine(watch.ElapsedMilliseconds);
Console.ReadLine();
}
public class Result
{
public List<string> fields { get; set; }
public string geometryType { get; set; }
public IEnumerable<ResultFeature> features { get; set; }
}
public class ResultFeature
{
public Dictionary<string, dynamic> attributes { get; set; }
public IEnumerable<IEnumerable<int>> geometry { get; set; }
}
public static IEnumerable<ResultFeature> CreateResultFeatures()
{
IWorkspace gdbWorkspace = FileGdbWorkspaceFromPath(#"\\vnageop1\geod\Maxime\test.gdb");
IFeatureWorkspace featureWorkspace = (IFeatureWorkspace)gdbWorkspace;
IFeatureClass featureClass = featureWorkspace.OpenFeatureClass(#"GEO09E04_MUNCP_GEN");
IQueryFilter queryFilter = new QueryFilterClass();
queryFilter.SubFields = "CD_MUNCP, NOM_MUNCP, SHAPE";
int cd_muncp_idx = featureClass.FindField("CD_MUNCP");
int nom_muncp_idx = featureClass.FindField("NOM_MUNCP");
using (ComReleaser comReleaser = new ComReleaser())
{
IFeatureCursor cursor = featureClass.Search(queryFilter, false);
comReleaser.ManageLifetime(cursor);
IFeature feature = null;
while ((feature = cursor.NextFeature()) != null)
{
ResultFeature resultFeature = new ResultFeature
{
attributes = new Dictionary<string,dynamic>
{
{ "CD_MUNCP", Convert.ToString(feature.Value[cd_muncp_idx]) },
{ "NOM_MUNCP", Convert.ToString(feature.Value[nom_muncp_idx]) }
},
geometry = PolygonToDeltas(feature.Shape as IPolygon4).ToLiist()
};
yield return resultFeature;
}
}
}
public static IEnumerable<IEnumerable<int>> PolygonToDeltas(IPolygon4 polygon)
{
IGeometryBag exteriorRingGeometryBag = polygon.ExteriorRingBag;
IGeometryCollection exteriorRingGeometryCollection = exteriorRingGeometryBag as IGeometryCollection;
for (int i = 0; i < exteriorRingGeometryCollection.GeometryCount; i++)
{
IGeometry exteriorRingGeometry = exteriorRingGeometryCollection.get_Geometry(i);
IPointCollection exteriorRingPointCollection = exteriorRingGeometry as IPointCollection;
yield return CreateDeltas(exteriorRingPointCollection);
IGeometryBag interiorRingGeometryBag = polygon.get_InteriorRingBag(exteriorRingGeometry as IRing);
IGeometryCollection interiorRingGeometryCollection = interiorRingGeometryBag as IGeometryCollection;
for (int k = 0; k < interiorRingGeometryCollection.GeometryCount; k++)
{
IGeometry interiorRingGeometry = interiorRingGeometryCollection.get_Geometry(k);
IPointCollection interiorRingPointCollection = interiorRingGeometry as IPointCollection;
yield return CreateDeltas(interiorRingPointCollection);
}
}
}
private static IEnumerable<int> CreateDeltas(IPointCollection pointCollection)
{
int previous_x = (int)pointCollection.get_Point(0).X;
int previous_y = (int)pointCollection.get_Point(0).Y;
yield return previous_x;
yield return previous_y;
for (int i = 1; i < pointCollection.PointCount; i++)
{
int current_x = (int)pointCollection.get_Point(i).X;
int current_y = (int)pointCollection.get_Point(i).Y;
yield return previous_x - current_x;
yield return previous_y - current_y;
previous_x = current_x;
previous_y = current_y;
}
}
}
}

Related

sorting a generic list from within a generic container class

I need to sort a list by any one of its properties, but i dont know which of these properties it will specifically be sorted on. The Main method below.
static void Main(string[] args)
{
Things<Something> something = new Things<Something>();
something.Add(new Something
{ Thing = "Apartment", Price = 1500000 });
something.Add(new Something
{ Thing = "Bed", Price = 10000 });
something.Add(new Something
{ Thing = "Lamp", Price = 600 });
something.Add(new Something
{ Thing = "Car", Price = 5000000 });
Console.WriteLine("\n\tStuff sorted by description");
something = something.SelectionSort("Thing");
foreach (Something thing in something)
Console.WriteLine("\t" + thing);
Console.WriteLine("\n\tStock items sorted by value");
something = something.SelectionSort("Value");
foreach (Something thing in something)
Console.WriteLine("\t" + thing);
Console.Write("\n\tPress any key to exit ...");
Console.ReadKey();
}
I have a struct
public struct Something
{
public string Thing { get; set; }
public decimal Price { get; set; }
}
And a generic container class called things
public class Things<T> : IEnumerable<T>
{
private List<T> lstItems;
public int Count { get { return lstItems.Count; } }
public Things() { lstItems = new List<T>(); }
public Things(List<T> items_) { lstItems = new List<T>(items_); }
public void Add(T item)
{
lstItems.Add(item);
}
public T this[int i]
{
get { return lstItems[i]; }
set { lstItems[i] = value; }
}
IEnumerator IEnumerable.GetEnumerator()
{
throw new System.NotImplementedException();
}
public IEnumerator<T> GetEnumerator()
{
foreach (T item in lstItems)
yield return item;
}
}
An extensions class extends the generic container class
public static class ExtensionsClass
{
private static string SortFiield { get; set; }
private static object GetProperty<T>(T thing, string nameofProp)
{
return thing.GetType().GetProperty(nameofProp).GetValue(thing, null);
}
private static int Compare<T>(T x, T y)
{
IComparable propX = (IComparable)GetProperty(x, SortFiield);
IComparable propY = (IComparable)GetProperty(y, SortFiield);
return propX.CompareTo(propY);
}
public static Things<T> SelectionSort<T>(this Things<T> things, string SORTFIELD)
{
List<T> lsstt = new List<T>(things);
int iIndex;
T temporary;
SortFiield = SORTFIELD;
for (int i = 0; i < lsstt.Count - 1; i++)
{
iIndex = i;
for (int j = i + 1; j < lsstt.Count; j++)
{
string first = GetProperty(lsstt[j], SortFiield).ToString();
string second = GetProperty(lsstt[iIndex], SortFiield).ToString();
if (Compare(first, second) < 0)
iIndex = j;
}
temporary = lsstt[i];
lsstt[i] = lsstt[iIndex];
lsstt[iIndex] = temporary;
}
return new Things<T>(lsstt);
}
}
The problem i am encountering is that get property in the extension class returns null, but i know that the object i am trying to return exists. It is found by the "String first = ...." line but when getproperty is called from the Compare method then it returns null.
You are passing "first", "second" to Compare. In your case both of them are strings and not objects, you need to pass "lsstt[j]" and "lsstt[iIndex]" to it.
if (Compare(lsstt[j], lsstt[iIndex]) < 0)
iIndex = j;

Table Row (//tr) HtmlNodes seem to have issue with rows being skipped

I'm currently trying to scrape a cannabis strain database as it is no longer being maintained. I seem to be running into an issue where table rows are skipped in my logic but it really doesn't make sense, it's like a break is being called when I'm iterating through the //tr elements of the table that is storing the chemical reports.
Is it something like the δ α symbols in the next row. I've tried regex replacing them out to now luck. Any help would be appreciated all code is in a single class console app.
Issue is in the table.ChildNodes not iterating all the way through. Located in the ParseChemical() method.
Sample Page: http://ocpdb.pythonanywhere.com/ocpdb/420/
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.Design;
using System.IO.IsolatedStorage;
using System.Linq;
using System.Linq.Expressions;
using System.Net;
using System.Net.Http;
using System.Reflection.Emit;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using HtmlAgilityPack;
using Microsoft.VisualBasic.CompilerServices;
namespace CScrape
{
class Program
{
private static readonly HttpClient Client = new HttpClient();
private static readonly string BaseUri = "http://ocpdb.pythonanywhere.com/ocpdb/";
private static int _startId = 420;
private static int _endId = 1519;
private static List<Lab> _labs = new List<Lab>();
private static List<ChemicalItem> _chemicalItems = new List<ChemicalItem>();
private static List<UnitOfMeasure> _uoms = new List<UnitOfMeasure>();
private static List<Strain> _strains = new List<Strain>();
static void Main(string[] args)
{
Client.DefaultRequestHeaders.Accept.Clear();
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls13;
_uoms.AddRange(GetUoms());
for (var i = _startId; i <= _endId; i++)
{
var result = GetUri($"{BaseUri}{i}").Result;
_strains.Add(ParseChemical(result));
}
}
private static long AddChemicalItem(ChemicalItem item)
{
if (ChemicalExists(item.Symbol))
return _chemicalItems.FirstOrDefault(ci => ci.Symbol == item.Symbol)?.Id ?? -1;
item.Id = _chemicalItems.Count + 1;
_chemicalItems.Add(item);
return item.Id;
}
private static void UpdateChemicalItem(ChemicalItem item)
{
if (!ChemicalExists(item.Symbol)) return;
var index = _chemicalItems.IndexOf(item);
if (!(index >= 0)) return;
_chemicalItems.RemoveAt(index);
AddChemicalItem(item);
}
private static long AddLab(Lab lab)
{
if (LabExists(lab.Name))
return _labs.FirstOrDefault(l => l.Name == lab.Name)?.Id ?? -1;
lab.Id = _labs.Count + 1;
_labs.Add(lab);
return lab.Id;
}
private static async Task<string> GetUri(string uri)
{
var response = await Client.GetByteArrayAsync(uri);
return Encoding.UTF8.GetString(response, 0, response.Length - 1);
}
private static Strain ParseChemical(string html)
{
html = Regex.Replace(html, #"Δ", "Delta");
HtmlDocument htmlDoc = new HtmlDocument();
htmlDoc.LoadHtml(html);
var strain = new Strain();
strain.Reports ??= new List<ChemicalReport>();
try
{
strain.Name = htmlDoc.DocumentNode.SelectSingleNode("/html/body/div/div[1]/div[1]/h3/b").InnerText;
}
catch (Exception e)
{
// TODO: DOcument Exception
Console.WriteLine(e.Message);
}
if (string.IsNullOrWhiteSpace(strain.Name)) return null;
try
{
var ocpId = htmlDoc.DocumentNode.SelectSingleNode("/html/body/div/div[1]/div[2]/p/b/text()[1]");
strain.OcpId = SanitizeHtml(ocpId.InnerText).Split(':')[1];
}
catch (Exception e)
{
// TODO: Document Exception
Console.WriteLine(e.Message);
}
if (string.IsNullOrWhiteSpace(strain.OcpId)) return null;
try
{
var date = htmlDoc.DocumentNode.SelectSingleNode("/html/body/div/div[1]/div[2]/p/text()");
}
catch (Exception e)
{
// TODO: Document Exception
Console.WriteLine(e.Message);
}
var chemReport = new ChemicalReport();
chemReport.Items ??= new List<ReportItem>();
try
{
var table = htmlDoc.DocumentNode.SelectSingleNode("/html/body/div/div[2]/div[1]/table/tbody");
var children = table.ChildNodes.ToList();
// On the sample page there are 200 children here
// However it only interates through the first few and then just breaks out of the loop
foreach (var child in children)
{
var name = child.Name;
if (child.Name == "tr")
{
var infos = child.SelectNodes("th|td");
foreach (var info in infos)
{
if(string.IsNullOrWhiteSpace(info.InnerText)) continue;
if (info.InnerText.Contains("Report")) continue;
if (double.TryParse(info.InnerText, out var isNumber))
{
var last = chemReport.Items.LastOrDefault();
if (last == null) continue;
if (last.Value <= 0.0000) last.Value = isNumber;
else
{
var further = chemReport.Items.ToArray()[chemReport.Items.Count - 2];
if (further.Value <= 0.0000)
further.Value = isNumber;
}
continue;
}
var _ = new ChemicalItem
{
Name = info.InnerText,
Symbol = info.InnerText
};
_.Id = AddChemicalItem(_);
var report = new ReportItem
{
Chemical = _,
ChemicalItemId = _.Id,
UnitOfMeasureId = 1,
UoM = GetUoms()[0]
};
chemReport.Items.Add(report);
}
}
}
strain.Reports.Add(chemReport);
}
catch (Exception e)
{
// TODO: Document exception
Console.Write(e.Message);
}
return strain;
}
private static List<UnitOfMeasure> GetUoms()
{
return new List<UnitOfMeasure>
{
new UnitOfMeasure {Name = "Milligrams per Gram", Symbol = "mg/g"},
new UnitOfMeasure {Name = "Percent", Symbol = "%"}
};
}
private static string SanitizeHtml(string text, string replacement = "")
{
return Regex.Replace(text, #"<[^>]+>| |α|\n|\t", replacement);
}
private static string GetLabName(string[] split)
{
var strip = split[0].Split(':')[1];
for(var i = 1; i < split.Length - 2; i ++)
{
if (string.IsNullOrWhiteSpace(split[i])) break;
strip += $" {split[i]}";
}
return strip;
}
private static string GetSampleId(string[] split)
{
var found = false;
foreach (var item in split)
{
if (found)
return item.Split(':')[1];
if (item == "Sample") found = true;
}
return "NA";
}
private static bool LabExists(string name)
{
return _labs.Any(lab => lab.Name == name);
}
private static bool ChemicalExists(string name)
{
return _chemicalItems.Any(ci => ci.Symbol == name);
}
private static ReportItem GetReportItem(string text)
{
if (string.IsNullOrWhiteSpace(text)) return null;
ReportItem ri = null;
try
{
var clean = SanitizeHtml(text);
var check = 0;
var split = clean.Split(':');
var label = split[0];
if (string.IsNullOrWhiteSpace(label)) return null;
if (double.TryParse(label, out var invalidType)) return null;
var val = string.Empty;
if (split.Length == 1)
{
if (split[0].Contains("Total"))
{
Regex re = new Regex(#"([a-zA-Z]+)(\d+)");
Match result = re.Match(split[0]);
label = result.Groups[1].Value;
val = result.Groups[2].Value;
}
}
if(split.Length > 1)
val = split[1];
if (!ChemicalExists(label)) AddChemicalItem(new ChemicalItem {Id = _chemicalItems.Count + 1,Symbol = label});
ri = new ReportItem();
ri.Chemical = _chemicalItems.FirstOrDefault(ci => ci.Symbol == label);
ri.UoM = val.Contains("%")
? _uoms.FirstOrDefault(uom => uom.Symbol == "%")
: _uoms.FirstOrDefault(uom => uom.Symbol == "mg/g");
if (string.IsNullOrWhiteSpace(val)) return ri;
var value = val.Contains("%") ? split[1].Substring(0, val.Length - 1) : val;
ri.Value = Convert.ToDouble(value);
}
catch (Exception e)
{
// TODO: Document Exception
Console.WriteLine(e.Message);
}
return ri;
}
//private static ChemicalItem GetChemicalItem(string text)
//{
//}
public class Strain
{
public long Id { get; set; }
public string Name { get; set; }
public DateTime Created { get; set; }
public string OcpId { get; set; }
public bool IsHidden { get; set; } = false;
public virtual ICollection<ChemicalReport> Reports { get; set; }
}
public class Lab
{
public long Id { get; set; }
public string Name { get; set; }
public virtual ICollection<ChemicalReport> Reports { get; set; }
}
public class ChemicalReport
{
public long Id { get; set; }
[ForeignKey("Lab")]
public long LabId { get; set; }
public virtual Lab Lab { get; set; }
public string SampleId { get; set; }
public DateTime Created { get; set; }
public virtual ICollection<ReportItem> Items { get; set; }
[ForeignKey("Strain")]
public long StrainId { get; set; }
public virtual Strain Strain { get; set; }
}
public class ChemicalItem
{
public long Id { get; set; }
public string Name { get; set; }
public string Symbol { get; set; }
}
public class ReportItem
{
public long Id { get; set; }
[ForeignKey("Chemical")]
public long ChemicalItemId { get; set; }
public virtual ChemicalItem Chemical { get; set; }
public double Value { get; set; }
[ForeignKey("UoM")]
public long UnitOfMeasureId { get; set; }
public virtual UnitOfMeasure UoM { get; set; }
}
public class UnitOfMeasure
{
public long Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string Symbol { get; set; }
}
}
}

C# Compare two list and return value

I have a problem. I try compare two list currentItemsInColl and bPList. Inside bPList i have other list RequiredItems and now is what I need.
I want compare currentItemsInColl and RequiredItems and return bPList.craftingBlueprint.
I try Compare but I dont know how use it :/
using Devdog.InventoryPro;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CraftingAutoUpdate : MonoBehaviour {
public ItemCollectionBase itemCollection;
public ItemCollectionBase rewardCollection;
public CraftingCategory craftingCategory;
[Header("Blue Print List")]
public List<BlueprintList> bPList = new List<BlueprintList>();
public List<CurrentItemInCollList> currentItemsInColl = new List<CurrentItemInCollList>();
private CraftingBlueprint readyBlueprint;
public void OnShow()
{
GetBluePrint();
InvokeRepeating("StartUpdate",0f,0.05f);
}
public void OnHide()
{
CancelInvoke("StartUpdate");
}
private void StartUpdate()
{
UpdateDirectory();
UpdateFindMatchItems();
UpdateCraftResults();
}
private void GetBluePrint()
{
bPList.Clear();
foreach (var b in craftingCategory.blueprints)
{
if (b != null)
{
var rI = b.requiredItems;
var listReqItems = new List<RequiredItem>();
foreach (var e in rI)
{
listReqItems.Add(new RequiredItem(e.item.ID, e.amount));
}
bPList.Add(new BlueprintList(b.name, b, listReqItems));
}
}
}
private void UpdateDirectory()
{
currentItemsInColl.Clear();
foreach(var item in itemCollection)
{
if (item.item != null)
{
var cT = item.item.ID;
if (currentItemsInColl.Find(u =>u.itemID == cT) == null)
{
var itemCount = itemCollection.GetItemCount(item.item.ID);
currentItemsInColl.Add(new CurrentItemInCollList(item.item.ID, itemCount));
}
}
}
}
In this methode I try find same items in collections:
private void UpdateFindMatchItems()
{
readyBlueprint = null;
bool matchFailed = false;
int requiredItemCount = 0;
int currentItemsInCollCount = currentItemsInColl.Count;
foreach(var bp in bPList)
{
requiredItemCount = bp.RequiredItems.Count;
foreach(var rI in bp.RequiredItems)
{
if(CompareLists(currentItemsInColl, bp.RequiredItems))
{
print("aa");
}
print(currentItemsInCollCount);
}
}
private void UpdateCraftResults()
{
rewardCollection.Clear();
if (readyBlueprint != null)
{
foreach (var items in readyBlueprint.resultItems)
{
rewardCollection.AddItem(items.item,null,true,false);
}
}
}
I try somthing like this but is wont work with this lists:
public static bool CompareLists<T>(List<T> aListA, List<T> aListB)
{
if (aListA == null || aListB == null || aListA.Count != aListB.Count)
return false;
if (aListA.Count == 0)
return true;
Dictionary<T,T> lookUp = new Dictionary<T,T>();
// create index for the first list
for (int i = 0; i < aListA.Count; i++)
{
uint count = 0;
if (!lookUp.TryGetValue(aListA[i], out count))
{
lookUp.Add(aListA[i], 1);
continue;
}
lookUp[aListA[i]] = count + 1;
}
for (int i = 0; i < aListB.Count; i++)
{
uint count = 0;
if (!lookUp.TryGetValue(aListB[i], out count))
{
// early exit as the current value in B doesn't exist in the lookUp (and not in ListA)
return false;
}
count--;
if (count <= 0)
lookUp.Remove(aListB[i]);
else
lookUp[aListB[i]] = count;
}
// if there are remaining elements in the lookUp, that means ListA contains elements that do not exist in ListB
return lookUp.Count == 0;
}
}
And this is my lists:
/* LISTS */
[Serializable]
public class CurrentItemInCollList
{
public uint itemID;
public uint itemAmount;
public CurrentItemInCollList(uint newitemID, uint newItemAmount)
{
itemID = newitemID;
itemAmount = newItemAmount;
}
}
[Serializable]
public class BlueprintList
{
public string bluePrintName;
public CraftingBlueprint craftingBlueprint;
public List<RequiredItem> RequiredItems = new List<RequiredItem>();
public BlueprintList(string newBluePrintName, CraftingBlueprint newcraftingBlueprint, List<RequiredItem> list)
{
bluePrintName = newBluePrintName;
craftingBlueprint = newcraftingBlueprint;
RequiredItems = list;
}
}
[Serializable]
public class RequiredItem
{
public uint itemID;
public uint itemAmount;
public RequiredItem( uint newitemID, uint newItemAmount)
{
itemID = newitemID;
itemAmount = newItemAmount;
}
}
I forgot.. CurrentItemInCollList.itemAmount can be >= RequiredItems.itemAmount
Dictionary use hash values to compare objects.
The stored classes must implement public override int GetHashCode(){}
Use Linq - here is a small console example:
class Program
{
static void Main(string[] args)
{
//Required list
List<Order> currentItemsInColl = new List<Order>();
currentItemsInColl.Add(new Order() { Name = "bike1", Id = "01" });
currentItemsInColl.Add(new Order() { Name = "bike4", Id = "04" });
//List of all items
List<BPP> bPList = new List<BPP>();
bPList.Add(new BPP() { BikeName = "bike1", Idzzz = "01" });
bPList.Add(new BPP() { BikeName = "bike2", Idzzz = "02" });
bPList.Add(new BPP() { BikeName = "bike3", Idzzz = "03" });
bPList.Add(new BPP() { BikeName = "bike4", Idzzz = "04" });
bPList.Add(new BPP() { BikeName = "bike5", Idzzz = "05" });
//Blueprint List
List<BPP> Blueprint = new List<BPP>();
//get all items into the Blueprint list
foreach (Order i in currentItemsInColl)
{
List<BPP> tmp = bPList.FindAll(x => x.Idzzz.Contains(i.Id));
//here you add them all to a list
foreach (BPP item in tmp)
{
Blueprint.Add(item);
}
}
Console.ReadLine();
}
}
public class Order
{
public string Id { get; set; }
public string Name { get; set; }
}
public class BPP
{
public string Idzzz { get; set; }
public string BikeName { get; set; }
}
Sidenote: i am comparing the ID's in each of the lists! Hope it helps.

yield return returning same result on each iteration

The problem is to generate combinations of search parameters to be used as test case inputs in automation tests.
public class CombinationInput<T>
{
public string Name { get; set; }
public List<T> PossibleValues { get; set; }
public bool ReadOnly { get; set; }
}
GetCombinations is a method in the Combinationsgenerator Class:
private IEnumerable<object[]> _GetCombinations(ArrayList inputs)
{
var returnobjects = new object[inputs.Count];
var element = inputs[0];
var type = element.GetType();
var generictype = type.GenericTypeArguments[0];
var elementvalues = type.GetProperty("PossibleValues").GetValue(element, null) as IEnumerable;
foreach (var val in elementvalues)
{
returnobjects[0] = val;
if (inputs.Count > 1)
{
var objs = _GetCombinations(inputs.GetRange(1, inputs.Count - 1));
foreach (var item in objs)
{
for (int i = 0; i < item.Length; i++)
{
returnobjects[i + 1] = item[i];
}
yield return returnobjects;
}
}
else
{
yield return returnobjects;
}
}
}
Inside TestMethod:
[TestMethod]
public void GetCombinationTest()
{
var x = new CombinationInput<Enums.AmountType>();
var y = new CombinationInput<Enums.AreaMeasureType>();
var z = new CombinationInput<Enums.DisplayItemType>();
ArrayList list = new ArrayList();
list.Add(x);
list.Add(y);
list.Add(z);
var combgen = new CombinationGenerator(list);
var combs = combgen.GetCombinations();
}
Get Combinations is always returning the same combination when I run the code but when I debug through the code each time it hits the yield return statement its having the right combination.
You always return the same object as you are editing the content itself. What you are yielding is the reference to an array, and it's always the same reference. Instead of reusing the same array, you should move the declaration and creation of returnobjects within the foreach loop.

Combining numbers and names collections

I have 2 List collections. One contains numbers, the other names. There are twice as many numbers as names(always). I want to take the first name from the collection and the first two numbers from the other collection then put them together in a 3rd user collection of (VentriloUser). Then the second name needs to be matched with the 3rd and 4th numbers and so on.
I was thinking something with a for or foreach loop, but I can't wrap my head around it right now.
public class VentriloUser
{
public VentriloUser(string name, int seconds, int ping)
{
Name = name; Seconds = seconds; Ping = ping;
}
public string Name { get; set; }
public int Ping { get; set; }
public int Seconds { get; set; }
}
public class Ventrilo
{
public Ventrilo(string statusurl)
{
StatusURL = statusurl;
}
public string StatusURL { get; set; }
public string HTML { get; set; }
public List<VentriloUser> Users { get; set; }
private Regex findNumbers = new Regex("\\<td width=\"10%\" bgcolor=\"#\\w{6}\"\\>\\<font color=\"#000000\">\\<div style=\"overflow:hidden;text-overflow:ellipsis\"\\>-?\\d+\\<");
private Regex findNames = new Regex("\\<td width=\"20%\" bgcolor=\"#\\w{6}\"\\>\\<font color=\"#000000\">\\<div style=\"overflow:hidden;text-overflow:ellipsis\"\\>\\b\\w+\\<");
private WebClient wClient = new WebClient();
public void DownloadHTML()
{
HTML = wClient.DownloadString(StatusURL);
}
public List<int> GetNumbers()
{
var rawnumbers = findNumbers.Matches(HTML);
var numbers = new List<int>();
foreach (var rawnumber in rawnumbers)
{
var match = Regex.Match(rawnumber.ToString(), "\\>\\-?\\d+\\<");
string number = Regex.Replace(match.ToString(), "\\<|\\>", "");
numbers.Add(Convert.ToInt32(number));
}
return numbers;
}
public List<string> GetNames()
{
var rawnames = findNames.Matches(HTML);
var names = new List<string>();
foreach (var rawname in rawnames)
{
var match = Regex.Match(rawname.ToString(), "\\>\\w+<");
string name = Regex.Replace(match.ToString(), "\\<|\\>", "");
names.Add(name);
}
return names;
}
public List<VentriloUser> GenerateUsers()
{
var numbers = GetNumbers();
var names = GetNames();
var users = new List<VentriloUser>();
}
}
I am a hobbyist, but hope to pursue a career one day. Any help is much appreciated. Thank you for your time.
Using LINQ:
var users = names.Select((name,idx) => new VentriloUser(name, numbers[idx*2], numbers[idx*2+1]))
.ToList();
Using loops:
var users = new List<VentriloUser>();
for (int i = 0; i < names.Count; i++)
{
var name = names[i];
int j = i * 2;
if (j >= numbers.Count - 1)
break; // to be safe...
users.Add(new VentriloUser(name, numbers[j], numbers[j + 1]));
}

Categories