I would like to create a list between a range of numbers with Razor, like the minimum number is 100,000 and the maximum is 1,200,000, so the list would be 100,000; 200,000; 300,000; ...1,200,000
100,000 would be the steps.
Unfortunately I have to put everything into a data attribute as a pricesList, so, so far I have this:
var developments = Model.Root().Children.Where(x => x.IsDocumentType("developments")).FirstOrDefault();
var prices = new List<int>();
var pricesList = "";
var priceValue = "";
var storedFloor = 0;
var storedCeiling = 0;
foreach (var development in developments.Children.Where(x => x.IsVisible())) {
var plots = development.Children.Where(x => x.IsVisible());
prices.AddRange(plots.Select(x => x.Value<int>("price")));
foreach (var price in prices.Distinct().OrderBy(x => x))
{
var floor = 0;
var ceiling = 0;
var storedPrice = price;
if(floor == ceiling){
storedPrice = price + 1;
}
floor = (int)(Math.Floor((int)price / 100000.0) * 100000);
ceiling = (int)(Math.Ceiling((int)storedPrice / 100000.0d) * 100000);
if(storedFloor != floor && storedCeiling != ceiling){
storedFloor = floor;
storedCeiling = ceiling;
priceValue = "£" + floor.ToString("#,##0") + " - " + "£" + ceiling.ToString("#,##0");
pricesList += "<option value='" + floor + "-" + ceiling + "'>" + @priceValue + "</option>";
}
}
}
This only gives me the min and max value by children, not together.
and i am not sure you wanted that (for example do you want the middle on to be £300,000 - £400,000) ?
So
Once you have all the prices grouped. If we assume that you just want the 100,000 ranges.
<select>
@for(int p = 0; p < prices.Count; p++)
{
var priceValue = string.Format("{0}-{1}", prices[p] - 1000000, prices[p]);
var priceString = string.Format("£{0:#,##0} - £{1:#,##0}", prices[p] - 100000, prices[p]);
<option value="@priceValue">@priceString</option>
}
</select>
this would return
£100,000 - £200,000
£300,000 - £400,000
£400,000 - £500,000
(if for example there are no 200,000 plot values)
So for compleatness (and with a step variable so you can change it).
@inherits UmbracoViewPage<IPublishedContent>
@{
var priceStep = 100000;
var prices = new List<int>();
// get all the prices from all the developments
var developments = Model.Root().Children.Where(x => x.IsDocumentType("developments")).FirstOrDefault();
foreach (var development in developments.Children.Where(x => x.IsVisible()))
{
var plots = development.Children.Where(x => x.IsVisible());
prices.AddRange(plots.Select(x => x.Value<int>("price")));
}
// round them up, and then pick only distinct the rounded up values.
prices = prices.Select(x => (int)(Math.Ceiling(x / (decimal)priceStep) * priceStep))
.Distinct().OrderBy(x => x).ToList();
// loop through the rounded values and produce the list
<select>
@for (int p = 0; p < prices.Count; p++)
{
var priceValue = string.Format("{0}-{1}", prices[p] - priceStep, prices[p]);
var priceString = string.Format("£{0:#,##0} - £{1:#,##0}", prices[p] - priceStep, prices[p]);
<option value="@priceValue">@priceString</option>
}
</select>
}
Yeah, my bad. Now for loop is outside of the foreach. Much-much better, however, some values are missing 400,000-500,000 ; 500,000-600,000 ; 600,000-700,000 etc
foreach (var development in developments.Children.Where(x => x.IsVisible()) {
var plots = development.Children.Where(x => x.IsVisible());
prices.AddRange(plots.Select(x => x.Value<int>("price")));
prices = prices.Select(x => (int)(Math.Ceiling(x / (decimal)priceStep) * priceStep)).Distinct().OrderBy(x => x).ToList();
}
for (int p = 0; p < prices.Count; p++) {
priceValue = string.Format("{0}-{1}", prices[p] - priceStep, prices[p]);
var priceString = string.Format("£{0:#,##0} - £{1:#,##0}", prices[p] - priceStep, prices[p]);
pricesList += "<option value='" + priceValue + "'>" + @priceString + "</option>";
}
They will be missing because there are no prices in those ranges ?
So there are two options,
you can either have all ranges, irrespective of them actually having values in ? e.g
100,000 - 200,000
200,000 - 300,000
300,000 - 400,000, etc
if so - you could probibly bypass the whole collection thing and put a for loop in to build them.
for(int p = priceStep; p < 1200000; p += priceStep)
{
// forloop will increment in 100,000's
// this doesn't need the prices array
var priceString = string.Format("£{0:#,##0} - £{1:#,##0}", p, p + priceStep);
// ....
}
or
If you still want to use the data but want the ranges to meet each other ,
e.g
£100,000 - £200,000
£200,000 - £300,000
£300,000 - £1,100,000
£1,100,000 - £1,200,000
then the first example did that, by doing the for loop from the second value (1 in the index) and then putting the p-1 value in the loop:
@for (int p = 1; p < prices.Count; p++)
{
var priceString = string.Format("£{0:#,##0} - £{1:#,##0}", prices[p - 1], prices[p]);
var priceValue = string.Format("{0}-{1}", prices[p - 1], prices[p]);
<option value="@priceValue">@priceString</option>
}
List of numbers between a range
Hi,
I would like to create a list between a range of numbers with Razor, like the minimum number is 100,000 and the maximum is 1,200,000, so the list would be 100,000; 200,000; 300,000; ...1,200,000 100,000 would be the steps. Unfortunately I have to put everything into a data attribute as a pricesList, so, so far I have this:
This only gives me the min and max value by children, not together.
Oh I like a little coding challenge 😊
I would swap the foreach out with a old school for loop, just because you can then go back in the loop to get the previous price.
So I assuming you are getting the prices from content nodes - into a list of ints called prices. if that list is ordered and a list.
UPDATE: OK so i missed that the prices where not the rounded numbers. the following will round those values into the nearest 100,000.
then i would use a for loop to start from the second item (1 in the index),
that gives you the list with ranges, .
OK,
I wasn't happy with that version :(
It returns whole lists e.g.
and i am not sure you wanted that (for example do you want the middle on to be £300,000 - £400,000) ?
So
Once you have all the prices grouped. If we assume that you just want the 100,000 ranges.
this would return
(if for example there are no 200,000 plot values)
So for compleatness (and with a step variable so you can change it).
HI Kevin,
Thank you for your help. I tried the code, now I have this version. Only difference that everything goes into a data attribute, like this:
Unfortunately, don't know how, but the result is the same:
Maybe just need to order by value and exclude the duplicates. Is that possible?
yeah i would split the loops out.
so do this to get all the prices across all the plots.
then distinct and round etc. after the loop
then the
for
loop - that way you get the distinct list across all developments,at the moment it looks like you are doing the for loop inside the other loop, not sure why is there a reason ?
Yeah, my bad. Now for loop is outside of the foreach. Much-much better, however, some values are missing 400,000-500,000 ; 500,000-600,000 ; 600,000-700,000 etc
They will be missing because there are no prices in those ranges ?
So there are two options,
you can either have all ranges, irrespective of them actually having values in ? e.g
if so - you could probibly bypass the whole collection thing and put a for loop in to build them.
or
If you still want to use the data but want the ranges to meet each other ,
e.g
then the first example did that, by doing the for loop from the second value (1 in the index) and then putting the p-1 value in the loop:
Thank you Kevin for you help, you really nailed it. Cheers!!
is working on a reply...