If I have this :
SubMenuList=new object[]
{
new
{
transKey = "PERSONAL_INFORMATION",
stateName="account.personalinformation",
displayUrl = "/account/personalinformation"
},
new
{
tranKey = "NOTIFICATIONS",
stateName = "account.notificationsettings",
displayUrl = "/account/notifications"
}
}
Can I somehow add an if statement to this and say for example:
if (something != null)
{
new
{
transKey = "PERSONAL_INFORMATION",
stateName="account.personalinformation",
displayUrl = "/account/personalinformation"
}
}
For this purpose is better to use List<Object>:
var list = new List<object>
{
new
{
transKey = "PERSONAL_INFORMATION",
stateName="account.personalinformation",
displayUrl = "/account/personalinformation"
}
};
if (something != null)
{
list.Add(new
{
tranKey = "NOTIFICATIONS",
stateName = "account.notificationsettings",
displayUrl = "/account/notifications"
});
}
if you want to get an array, you can invoke ToArray() on the link:
SubMenuList = list.ToArray();
It is better to introduce non anonymous type here, because these objects have the same structure, and without the context it is hard to guess why you do not use named types.
You can use a list with real type, as suggested by #DavidArno, and add the new item to the list if something != null.
You can also use anonymous types:
var list = new[]
{
new
{
transKey = "PERSONAL_INFORMATION",
stateName="account.personalinformation",
displayUrl = "/account/personalinformation"
},
new
{
transKey = "NOTIFICATIONS",
stateName = "account.notificationsettings",
displayUrl = "/account/notifications"
}
}.ToList()
if (something != null)
{
list.Add(new
{
transKey = "PERSONAL_INFORMATION",
stateName="account.personalinformation",
displayUrl = "/account/personalinformation"
});
}
If you don't need to access the members of the anonymous type (e.g. list[0].transKey) or are okay with using reflection, Alex's answer might be better suited for your question.
Related
var result = new List<QuickSearchModel>();
var Navmenus = CommonConstants.GetNavItems();
var items = new List<NavMenuItem>();
Navmenus.ForEach(it =>
{
if (it.IsNested)
{
it.menuItems.ForEach(mi => items.Add(new NavMenuItem() { Name = it.Name + "/" + mi.Name, Link = mi.Link }));
}
else {
items.Add(new NavMenuItem() { Name = it.Name, Link = it.Link });
result.Add(new QuickSearchModel() { Id = "1", Title = it.Name, ItemType = it.Name, Route = it.Link });
}
});
return result;
At the end of my code block when I am returning my results, I am expecting 26 items.
In my immediate window, i type items and I see 26 NavMenuItems listed
when I type result, i see 1 QuickSearchModel listed (the 3rd in my items list)
Please see these two images as reference
SOLUTION:
I ultimately did this
public static List<QuickSearchModel> PageListFromNavMenu()
{
var Navmenus = CommonConstants.GetNavItems();
var items = new List<NavMenuItem>();
Navmenus.ForEach(it =>
{
if (it.IsNested)
{
it.menuItems.ForEach(mi => items.Add(new NavMenuItem() { Name = it.Name + "/" + mi.Name, Link = mi.Link }));
}
else {
items.Add(new NavMenuItem() { Name = it.Name, Link = it.Link });
}
});
return PageListFromNavMenu(items);
}
private static List<QuickSearchModel> PageListFromNavMenu(List<NavMenuItem> items)
{
var result = new List<QuickSearchModel>();
items.ForEach(it =>
{
result.Add(new QuickSearchModel() { Id="1", Title = it.Name, ItemType = it.Name, Route = it.Link });
});
return result;
}
It's a shame that I had to run through a 2nd For Loop to get the results but it did work. I wish I could have just have done it in the else block.
Why are you creating a list of NavMenuItems just to convert it to a list of QuickSearchModels? Create QuickSearchModels in your first method (and never create an intermediate List<NavMenuItem>)
public static List<QuickSearchModel> PageListFromNavMenu()
{
var Navmenus = CommonConstants.GetNavItems();
var items = new List<QuickSearchModel>();
Navmenus.ForEach(it =>
{
if (it.IsNested)
{
foreach (var mi in it.menuItems) {
string name = it.Name + "/" + mi.Name;
items.Add(new QuickSearchModel {
Id = "1",
Title = name,
ItemType = name,
Link = mi.Link
});
}
}
else {
items.Add(new QuickSearchModel {
Id = "1",
Title = it.Name,
ItemType = it.Name,
Link = it.Link
});
}
});
return items;
}
Well... Because the code says so. If the NavMenu-item is nested, add something to items colletion, otherwise add it to items and result collection. Obviously you have one root element and 25 child items.
I have some object models like this :
var x= new XModel()
{
end_date = "2017-12-15",
page = 1,
start_date = "2014-12-01",
group_by = new List<string> { "numbers" },
filter = new Filter() { numbers= new List<int> {1620} ,names= null, deleted= null, added = null }
};
or this one :
var y= new YModel
{
Title = "test title",
GenderType = Gender.Men,
Oss = "ALL",
Devices = new List<string> { "11", "12" },
Categories = new List<string> { "11", "12" },
}
i want to add these models to the list, the problem is , i tried to wrote a generic method to add all object models like above to the list.
My current method is :
internal static List<UrlParameter> GetParams<TModel>(this TModel entity)
{
var parameters = new List<UrlParameter>();
foreach (var propertyInfo in entity.GetType().GetProperties())
{
var propVal = propertyInfo.GetValue(entity, null);
if (propVal == null)
{
parameters.Add(new UrlParameter(propertyInfo.Name, ""));
continue;
}
if (propertyInfo.PropertyType.IsGenericType)
{
if (propVal.GetType().IsPrimitiveType())
{
parameters.Add(new UrlParameter(propertyInfo.Name, propVal));
}
else
{
var arr = propVal as IEnumerable;
if (arr.HasArrayContainPrimitiveType())
parameters.Add(new UrlParameter(propertyInfo.Name, $"[{ToJsonArray(arr)}]"));
else
parameters.AddRange(from object obj in arr
select GetParams(obj)
into subparams
select new UrlParameter(propertyInfo.Name, subparams));
}
}
else
{
if (propVal.GetType().IsPrimitiveType())
parameters.Add(new UrlParameter(propertyInfo.Name, propVal));
else
{
var subparams = GetParams(propVal);
parameters.Add(new UrlParameter(propertyInfo.Name, subparams));
}
}
}
return parameters;
}
it works fine for most of my models, but the x where contains filter makes me a problem, the numbers value saved like this filter=numbers%3d%255b1620%255d%2c%2c%2c%2c%2c%2c%2c , and the rest of the fields disappeare.
i want to add numbers, names, deleted and added as key, value parameter nested in filter, can you please help me to fixed this?
I solved my problem by using MultipartFormDataContent class.
it converts all the nested model as they are.
I have two lists which i want to get the different items from them
SearchElement[] criteria = new SearchElement[] {
new SearchElement
{
Comparison = "=",
FieldName = "CableProperty.ProjectId",
FieldValue = int.Parse(comboBoxSource.SelectedValue.ToString()),
LogicalOperator = "" }
};
sourceCables = client.GetCables(criteria, null, "Cores,CableProperty,CableProperty.CableApplication").ToList();
criteria = new SearchElement[] {
new SearchElement
{
Comparison = "=",
FieldName = "CableProperty.ProjectId",
FieldValue = int.Parse(comboBoxDestination.SelectedValue.ToString()),
LogicalOperator = "" }
};
destinationCables = client.GetCables(criteria, null, "Cores,CableProperty,CableProperty.CableApplication").ToList();
diffCables = sourceCables.Except(destinationCables, new CableComparer())
.ToList();
Now I have the different items in diffcable. Sometimes i want to set
diffCable.CableProperty.CableApplication = null;
but when i do that, all the navigation Porperty(CableApplication) in sourcelist is also set to null.
this is the code
if (destinationCableApplications.Contains(diffCable.CableProperty.CableApplication, new CableApplicationComparer()))
{
criteria = new SearchElement[] { new SearchElement { Comparison = "=", FieldName = "ProjectId", FieldValue = int.Parse(comboBoxDestination.SelectedValue.ToString()), LogicalOperator = "" }};
cableApplication = client.GetCableApplications(criteria, null, "").SingleOrDefault();
diffCable.CableProperty.CableApplication = null;
}
excatly in after this line
diffCable.CableProperty.CableApplication = null;
all the
sourcecables[0].CableProperty.CableApplication
sourcecables[1].CableProperty.CableApplication
.....
sourcecables[100].CableProperty.CableApplication
are set to null
what should i do to not lose the navigation property in sourcelist when i set null to navigation property in diffcable ?
easiest way is using MemoryStream..
Here is a sample,
[Serializable]
public class temp
{
public int a;
}
class Program
{
public static T DeepClone<T>(T a)
{
using (MemoryStream stream = new MemoryStream())
{
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, a);
stream.Position = 0;
return (T)formatter.Deserialize(stream);
}
}
static void Main(string[] args)
{
List<temp> list1 = new List<temp>();
list1.Add(new temp { a = 1 });
list1.Add(new temp { a = 2 });
list1.Add(new temp { a = 3 });
List<temp> list2 = DeepClone<List<temp>>(list1);
list1[1].a = 4;
Console.WriteLine(list2[1].a);
Console.ReadKey();
}
}
Note: class must be Serializable.
This will work for all value and reference types.
You are doing a copy by reference without realising it. Look into Cloning your objects or creating new lists.
List<int> newCopyList = new List<int>(originalList);
I'm searching a sorted dictionary with a key of type datetime and values as list of objects. What I need to find is the latest value(based on a property on the object) for each object in the dictionary. My object has 3 properties : a name, a value and a date when it was created. My dictionary is sorted by latest date in descending order.
I have got this working somehow, but I'm sure there is a shortcut for this using LINQ. Please note that I'm using .NET 3.5. Could you please help? Please dont get put off by the huge amount code below as I have added it for clarity and i'm only looking for a linq query to query inside a list of list objects.
Code below:
public void Should_link_recent_data_together()
{
var data = TimeSeriesDataFactoryEx.GetData();
var allAttributes = new List<string>()
{
TimeSeriesConstants.TOTAL_COST_CODE,
TimeSeriesConstants.TOTAL_VALUE_CODE,
TimeSeriesConstants.SOURCE_CODE
};
var latestList = new List<TimeSeries>();
var allValues = data.Values.ToList();
#region HOW DO I DO THIS USING LINQ?
bool found = false;
foreach (var attribute in allAttributes)
{
found = false;
foreach (var tsData in allValues)
{
foreach (var ts in tsData)
{
if (ts.MetricName == attribute && !string.IsNullOrEmpty(ts.MetricValue))
{
latestList.Add(ts);
found = true;
break;
}
}
if (found)
break;
}
}
#endregion
Assert.IsTrue(latestList.Count == 3);
Assert.IsTrue(latestList.Where(x => x.MetricName == TimeSeriesConstants.TOTAL_COST_CODE).First().MetricValue == "1");
Assert.IsTrue(latestList.Where(x => x.MetricName == TimeSeriesConstants.TOTAL_VALUE_CODE).First().MetricValue == "2");
Assert.IsTrue(latestList.Where(x => x.MetricName == TimeSeriesConstants.SOURCE_CODE).First().MetricValue == "gp");
Assert.IsTrue(latestList.Where(x => x.MetricName == TimeSeriesConstants.SOURCE_CODE).First().Quarter == DateTime.Today.AddMonths(-3));
}
internal class TimeSeriesDataFactoryEx
{
public static SortedDictionary<DateTime?,List<TimeSeries>> GetData()
{
return new SortedDictionary<DateTime?, List<TimeSeries>>(new DateComparer())
{
{
DateTime.Today, new List<TimeSeries>()
{
new TimeSeries()
{
Quarter = DateTime.Today,
MetricValue = "1",
MetricName = TimeSeriesConstants.TOTAL_COST_CODE
},
new TimeSeries()
{
Quarter = DateTime.Today,
MetricValue = "2",
MetricName = TimeSeriesConstants.TOTAL_VALUE_CODE
},
new TimeSeries()
{
Quarter = DateTime.Today,
MetricValue = "",
MetricName = TimeSeriesConstants.SOURCE_CODE
}
}
},
{
DateTime.Today.AddMonths(-3), new List<TimeSeries>()
{
new TimeSeries()
{
Quarter = DateTime.Today.AddMonths(-3),
MetricValue = "3",
MetricName = TimeSeriesConstants.TOTAL_COST_CODE
},
new TimeSeries()
{
Quarter = DateTime.Today.AddMonths(-3),
MetricValue = "4",
MetricName = TimeSeriesConstants.TOTAL_VALUE_CODE
},
new TimeSeries()
{
Quarter = DateTime.Today.AddMonths(-3),
MetricValue = "gp",
MetricName =TimeSeriesConstants.SOURCE_CODE
}
}
}
};
}
}
So, assuming I understand your question right, say you have a dictionary like so:
{ Key = "1/1/1900", Value = List Of Objects, of which each has a DateTimeProperty }
...
{ Key = "1/4/1900", Value = List Of Objects, of which each has a DateTimeProperty }
And you are looking to find a set of objects from your dictionary, where it's the latest by time of each key, then you can do this pretty simply with linq:
var latestItems = data.SelectMany(kvp =>
kvp.Value.OrderByDescending(value => value.Quarter).Take(1)
);
This query finds the most recent object in each bucket and then returns that as a single set (not an enumerable of enumerables). You can change the selector inside the SelectMany to find elements in each set as much as you want, as long as you return an IEnumerable from that callback.
I am building a workflow in my code, and I don't know how I can add a simple (While) condition. Tried to figure out how, but no luck with it, search on the internet but no luck either.
This is a simplified version of what I am trying to do:
ActivityBuilder ab = new ActivityBuilder();
ab.Implementation = new Sequence()
{
Variables =
{
new Variable<int>("StepNo", 0)
},
Activities =
{
new While()
{
Condition = <the_condition>
Body =
{
//Some logic here and the StepNo is increased
}
}
}
}
The While condition should be something like "StepNo < 10". Any idea how can this be made?
var stepNo = new Variable<int>("stepNo", 0);
var activity = new Sequence
{
Variables =
{
stepNo
},
Activities =
{
new While
{
Condition = new LessThan<int,int,bool>
{
Left = stepNo,
Right = 10
},
Body = new Sequence
{
Activities =
{
new Assign<int>
{
To = stepNo,
Value = new Add<int, int, int>
{
Left = stepNo,
Right = 1
}
},
new WriteLine
{
Text = new VisualBasicValue<string>("\"Step: \" & stepNo")
}
}
}
}
}
};
Or a version without expression activities but only with VisualBasicValue, which is also an activity:
var stepNo = new Variable<int>("stepNo", 0);
var activity = new Sequence
{
Variables =
{
stepNo
},
Activities =
{
new While
{
Condition = new VisualBasicValue<bool>("stepNo < 10"),
Body = new Sequence
{
Activities =
{
new Assign<int>
{
To = stepNo,
Value = new VisualBasicValue<int>("stepNo + 1")
},
new WriteLine
{
Text = new VisualBasicValue<string>("\"Step: \" & stepNo")
}
}
}
}
}
};