Is there any property or function for DynamicNodeList which returns the number of list items.
This is my code:
var root = Model.NodeById(id);
var nodes = root.Descendants("ChartItem");
if (nodes.GetLength() > 0)
{
s = s + "<ul>";
}
But GetLength is not a valid function. what should I do?
There is a built in extension method for IEnumerable types called Count(), it does just that, it counts the items :)
See code below:
var root = Model.NodeById(id);
var nodes = root.Descendants("ChartItem");
if (nodes.Count() > 0)
{
s = s + "<ul>";
}
Looking here
http://umbraco.com/follow-us/blog-archive/2011/12/22/umbraco-5-rc1-is-out-today.aspx
I would try (not sure if the null check is required, or if Descendants() returns at least an empty list)
nodes != null && nodes.Count() >0
or
nodes != null && nodes.Any()
Try this code:
var root = Model.NodeById(id);
var nodes = root.Descendants("ChartItem");
int nodesCount = 0;
foreach (var node in nodes)
{
nodesCount += 1;
}
if (nodesCount > 0)
{
s = s + "<ul>";
}
Related
I'm trying to create a tree-like structure. Every class has a parent field and list of children, that is the same class as the parent class. Basic stuff.
Here's a basic version of the class I'm using.
public class TreeElement {
public string name;
public int depth;
public int id;
public TreeElement parent;
public List<TreeElement> children = new List<TreeElement>();
}
Now, when I get the initial data, I get all of these classes in a list. Every item in my tree view is in one big list, and all I can go on is the depth value and the index of the item in the list. So the list would basically look something like this:
(0) -1
(1) |- 0
(2) |-- 1
(3) |-- 1
(4) | |-- 2
(5) |-- 1
(x) means the index in the list. The rest of the numbers are the depth values.
Now to my actual problem. I am having a really hard time making my own list based on these values and I've basically only gotten to where a single item in every child gets added and the siblings get ignored. I really can't find a way to take those into account.
Here's my code so far (which is probably horribly wrong for this):
private List<TreeElement> GenerateTreeStructure(List<TreeElement> baseList)
{
// Base list is the list I get provided with.
List<TreeElement> newList = new List<TreeElement>();
TreeElement root = null;
TreeElement previousFolder = null;
int previousdepth = -99;
for (int i = 0; i < baseList.Count; i++)
{
TreeElement currentResource = baseList[i];
if (currentResource.depth == -1 && ShowRootFolder) // The root folder.
{
root = currentResource;
// (Name, depth, parent)
newList.Add(new TreeElement("Root", currentResource.depth, null));
previousFolder = root;
previousdepth = root.depth;
}
else if (!ShowRootFolder && currentResource.depth <= 0)
{
// If root folder is not shown, take all the children of the root folder instead.
if (currentResource.depth != -1)
{
previousFolder = new TreeElement(currentResource.name, currentResource.depth, null);
previousdepth = previousFolder.depth;
newList.Add(previousFolder);
}
}
else
{
if (currentResource.depth > previousdepth)
{
TreeElement newResource = new TreeElement(currentResource.name, currentResource.depth, null);
previousFolder.children.Add(newResource);
previousdepth = currentResource.depth;
previousFolder = newResource;
}
}
}
return newList;
}
I hope that explains my problem. I've been stuck with this for quite a while and I hope to get some help with this!
Thanks
It's a bit puzzling why you are returning a list of TreeElement from that GenerateTreeStructure function? You are making a tree structure right? You should be returning just the rootnode? Anyhow, this takes a list with depth values and makes a tree out of it:
public static TreeElement GenerateTreeStructure(List<TreeElement> baseList)
{
TreeElement root = null;
if (baseList == null || baseList.Count == 0) return root;
int baseIdx = -1;
TreeElement prevNode = null;
TreeElement parent = null;
while (baseIdx < baseList.Count - 1)
{
baseIdx++;
TreeElement item = baseList[baseIdx];
if (item.depth == -1)
{
root = new TreeElement("root", -1, null);
prevNode = root;
continue;
}
if (item.depth == prevNode.depth) parent = prevNode.parent; // same level as prevNode
else if (item.depth > prevNode.depth) parent = prevNode; // deeper
else // shallower
{
parent = prevNode.parent;
while (parent.depth >= item.depth) parent = parent.parent;
}
TreeElement newNode = new TreeElement(item.name, item.depth, parent);
parent.children.Add(newNode);
prevNode = newNode;
}
return root;
}
// to test
void Traverse(TreeElement branch, int depth)
{
log(new string('\t', depth) + branch.name);
foreach (var subBranch in branch.children) Traverse(subBranch, depth+1);
}
Traverse(root, 0);
I`ve found two mistakes in logic. Here is fixed code:
// Base list is the list I get provided with.
List<TreeElement> newList = new List<TreeElement>();
TreeElement root = null;
TreeElement previousFolder = null;
int previousdepth = -99;
for (int i = 0; i < baseList.Count; i++)
{
TreeElement currentResource = baseList[i];
if (currentResource.depth == -1 && ShowRootFolder) // The root folder.
{
root = new TreeElement("Root", currentResource.depth, null);
// (Name, depth, parent)
newList.Add(root);
previousFolder = root;
previousdepth = root.depth;
}
else if (!ShowRootFolder && currentResource.depth <= 0)
{
// If root folder is not shown, take all the children of the root folder instead.
if (currentResource.depth != -1)
{
previousFolder = new TreeElement(currentResource.name, currentResource.depth, null);
previousdepth = previousFolder.depth;
newList.Add(previousFolder);
}
}
else
{
if (currentResource.depth > previousdepth)
{
TreeElement newResource = new TreeElement(currentResource.name, currentResource.depth, previousFolder);
previousFolder.children.Add(newResource);
previousdepth = currentResource.depth;
previousFolder = newResource;
}
}
}
return newList;
In first "if" statement you created new Root but did not assign it to root object and therefore did not assign it to previousFolder object, which you use in last "if" statement. Also you did not pass previousFolder object to constructor of TreeElement in last if statement and it would cause problems if you tried go to root element from the bottom using parent field.
P.S. Code is very strange and it seems like you are just starting to learn. If we are talking about tree structure, I would suggest to read about Composite pattern to create a tree in couple with Visitor pattern to 'visit' it.
I have list of 10 Iwebelements . i've stored their text into another list(As i just need to check that all 10 are in Alphabetical Order)
Can any one please tell me how to do that .
(Below code will get the list of all elements and with Foreach i'm getting their text and adding them into X list)
IList<IWebElement> otherSports = Driver.FindElements(By.CssSelector(".sports-buttons-container .other-sport .sport-name"));
List<string> x = new List<string>();
foreach (var item in otherSports)
{
string btnText = item.Text.Replace(System.Environment.NewLine, "");
x.Add(item.Text.Replace(System.Environment.NewLine, ""));
}
Note:- I dont want to sort the list . I just want to see if all items in List X is in Alphabetical order.
Any Help would be appreciated.
You can use StringComparer.Ordinal to check if two strings are in alphabetical order.
var alphabetical = true;
for (int i = 0; i < x.Count - 1; i++)
{
if (StringComparer.Ordinal.Compare(x[i], x[i + 1]) > 0)
{
alphabetical = false;
break;
}
}
An alternative solution if you prefer LINQ(but less readable, IMO)
var alphabetical = !x.Where((s, n) => n < x.Count - 1 && StringComparer.Ordinal.Compare(x[n], x[n + 1]) > 0).Any();
EDIT since you are generating the list your self, you can add solution 1 into your code when the list is created, that's more efficient.
IList<IWebElement> otherSports = Driver.FindElements(By.CssSelector(".sports-buttons-container .other-sport .sport-name"));
List<string> x = new List<string>();
var alphabetical = true;
string previous = null;
foreach (var item in otherSports)
{
string btnText = item.Text.Replace(System.Environment.NewLine, "");
var current = item.Text.Replace(System.Environment.NewLine, "");
x.Add(current);
if (previous != null && StringComparer.Ordinal.Compare(previous,current) > 0)
{
alphabetical = false;
}
previous = current;
}
I would do it like that
[TestMethod]
public void TestOrder()
{
IList<IWebElement> otherSports = Driver.FindElements(By.CssSelector(".sports-buttons-container .other-sport .sport-name"));
var x = otherSports.Select(item=>item.Text.Replace(System.Environment.NewLine, ""))
var sorted = new List<string>();
sorted.AddRange(x.OrderBy(o=>o));
Assert.IsTrue(x.SequenceEqual(sorted));
}
So this method will fail untill list x list is ordered alphabetically
I have managed to pull out the FirstorDefault() in the Query, however, some of these address types in the database actually have more than 1 address: therefore, I am trying to build an array of every address regarding each one.
The current code:
int counter = 0;
string queryID = "";
List<string> busAddr = new List<string>();
while (counter != busIDs.Count)
{
queryID = busIDs[counter];
var gathered = (from c in db.tblbus_address where c.BusinessID == queryID && c.AddressTypeID == addrnum select c).ToArray();
int gath = 0;
if ((gathered[gath] as tblbus_address) != null && !string.IsNullOrEmpty((gathered[gath] as tblbus_address).Address1))
{
var address = gathered[gath] as tblbus_address;
string test = "";
while (gath != address.Address1.Length)
{
var all = address.Address1;
test += address.Address1.ToString() + ",";
}
busAddr.Add(test);
}
else
{
busAddr.Add("No address for this type exists...");
}
counter++;
gath++;
}
I am receiving an error:
Index was outside the bounds of the array.
at this line:
if ((gathered[gath] as tblbus_address) != null && !string.IsNullOrEmpty((gathered[gath] as tblbus_address).Address1))
Can anyone point me in the right direction? I know this structure is the issue but I cannot think how to approach the situation.
You are trying to get the element gathered[gath] when there are no items in gathered. Adding a check for null and Any will help you
if(gathered!=null && gathered.Any()
&& (gathered[gath] as tblbus_address) != null
&& !string.IsNullOrEmpty((gathered[gath] as tblbus_address).Address1))
{
...
...
}
I have an array as
That is, each item has its category in the following index.
I need all the items whose category are TotalNumbers and CurrentNumbers.
I tried
int i = 1;
foreach (string item in statsname)
{
//only number type stats are added to the comboboxes.
if ((statsname[i].ToUpperInvariant()==("TOTALNUMBER")) || ((statsname[i].ToUpperInvariant()==("CURRENTNUMBER"))))
{
comboBox1.Items.Add(statsname[i-1]);
i++;
i++;
}
comboBox1.SelectedIndex = 0;
}
Apparently this does not checks for what I need correctly.
How do I need to modify my codes to get what i need ?
Seems it's better to use a for loop instead of foreach:
for (int i = 1; i < statsname.Length; i += 2)
{
//only number type stats are added to the comboboxes.
if ((statsname[i].ToUpperInvariant()==("TOTALNUMBER")) || ((statsname[i].ToUpperInvariant()==("CURRENTNUMBER"))))
comboBox1.Items.Add(statsname[i-1]);
}
Linq comes to rescue!
var listItems = from s in statsname where s.Equals("TOTALNUMBER", StringComparison.InvariantCultureIgnoreCase) || s.Equals("CURRENTNUMBER", StringComparison.InvariantCultureIgnoreCase) select new ListItem(s);
comboBox1.AddRange(listItems);
Code not tested or compiled, but you can have an idea of what i said.
var filteredValues = Array.FindAll(source, s => s.ToUpperInvariant() == "TOTALNUMBER" ||
s.ToUpperInvariant() == "CURRENTNUMBER").ToList()
I am not sure why you are using index in an foreach loop. The below code should work for you
foreach (string item in statsname)
{
if ( item.ToUpper() == "TOTALNUMBER" || item.ToUpper() == "CURRENTNUMBER")
{
comboBox1.Items.Add(item);
}
}
comboBox1.SelectedIndex = 0;
I'm trying to select only those rows which have Parent ID = 0
int predecessor = Parent;
StringBuilder valuePath = new StringBuilder();
valuePath.Append(Parent.ToString());
DataRow[] drPar;
while (true)
{
drPar = dt.Select("MenuID=" + predecessor);
if (drPar != null)
{
if (drPar[0]["ParentID"].ToString().Equals("0"))
break;
}
drPar[0]["ParentID"].ToString().Equals("0") is giving me
Out of Bound exception ..
Help Please !
DataTable.Select does not return null when there's no matching DataRow but an array with Length==0.
But apart from that, why are you using an "infinite" loop for only one statement?
So this should work:
drPar = dt.Select("MenuID=" + predecessor);
if (drPar.Length != 0)
{
if (drPar[0]["ParentID"].ToString().Equals("0"))
{
// ...
}
}
The array drPar must be empty to give this error as it is the only index you use in your code.
Try
if (drPar != null && drPar.Length > 0)