2

I have a list called blogCategoriesList (which is of type string) that is populated with the value of each blog category as it loops through each page by checking the value defined in the category dropdown property. So if I had three blog posts on my site and the categories were defined as football, darts, darts then this is what the list would contain.

I am trying to do an if check that verifies whether

  • the list contains a value that is the same category as the currentpage
  • the list contains more than one entry that is the same as the category of the current page

Examples

blogCategoriesList = football, darts, darts

if I was on a page that had the category set as darts then the if test should pass because the list contains darts and it also has more than one entry for darts in the list.

blogCategoriesList = football, Computing, darts

if I was on a page that had the category set as darts then the if test would fail because the list contains darts but it doesnt have more than one entry for darts in the list.

I have been trying to work with the following code that uses groupby but struggling to get this to work at the moment.

@if (blogCategoriesList.Contains(Model.Content.GetPropertyValue("category")) && blogCategoriesList.GroupBy(n => n.Equals(Model.Content.GetPropertyValue("category"))).Any(c => c.Count() > 1))

Any help would be great

Many thanks

Paul

Edit* so using the suggestions below i have updated my code to

 @if (blogCategoriesList.Contains(@Model.Content.GetPropertyValue("category")) && blogCategoriesList.Where(x => x == @Model.Content.GetPropertyValue("category")).Count() > 1)

 @if (blogCategoriesList.Contains(@Model.Content.GetPropertyValue("category")) && blogCategoriesList.Where(x => x == @Model.Content.GetPropertyValue("category")).Skip(1).Any())

but now my if test is always failing and doesnt make sense. The current page is of category computing. You can see from my debug that there is more than one computing value in the category list

enter image description here

ekad
  • 14,436
  • 26
  • 44
  • 46
Paul
  • 620
  • 11
  • 35
  • 3
    `blogCategoriesList.Where(c => c == category).Count() > 1`? – CodeCaster Feb 03 '16 at 11:40
  • 1
    `blogCategoriesList.Where(c => c == category).Skip(1).Any()`? There's no need to scan all the list to find out that the `Count()`, say, `1234567` – Dmitry Bychenko Feb 03 '16 at 11:46
  • @Paul See the edit to my answer. – Fᴀʀʜᴀɴ Aɴᴀᴍ Feb 03 '16 at 12:18
  • 1
    There is no need to do a `Contains()` _and_ a `Count()`. If the count > 0, then contains will logically be true. Please inspect the actual type of `@Model.Content.GetPropertyValue("category")`, I suspect it to be `object`. – CodeCaster Feb 03 '16 at 12:37
  • @CodeCaster you are absolutely correct. It was an object. I stored it in a var (var currentPageCategory = Model.Content.GetPropertyValue("category").ToString();) and converted to string and it resolved the issue. Thanks for all your help everyone. so which do i mark as the answer? – Paul Feb 03 '16 at 12:43

2 Answers2

11

In case of long list

  if (blogCategoriesList.Where(c => c == category).Skip(1).Any()) {
    ...
  }

will be a faster than Count solution: there's no need to compute exact number of items (say, 1234567) just the fact that this number exceeds 1.

Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
0

The return type of Umbraco's @Model.Content.GetPropertyValue() is object.

This causes your comparison (and thus your code) to fail, see Compare string and object in c# and this small demo:

var stringList = new List<string>
{
    "foo",
    "bar",
};

// prevent string interning, which will cause reference equality to be true
object needle = "fo";
needle = (string)needle + "o"; 

bool listContainsNeedle = stringList.Contains(needle);

var needleInList = stringList.Where(s => s == needle).ToList();

Now listContainsNeedle will be true (as it in fact does a string comparison), but needleInList will have 0 entries because it tests for reference equality.

To get the property as a string, use GetPropertyValue<string>(), which will make your code work. Alternatively cast the needle to string explicitly:

Where(s => s == (string)needle)
Community
  • 1
  • 1
CodeCaster
  • 147,647
  • 23
  • 218
  • 272