select value from array at desired index using LINQ - c#

i have an array which have 5 values from index 0 to 4. i want to store the values in my 5 model properties.
public IEnumerable<fields> ConvertTList(List<string[]> rows)
{
var tList = new List<fields>();
foreach (var item in rows)
{
var ListReading = new fields
{
//model properties names are:
// date, user,campaign,adgroup,changes
};
tList.Add(ListReading);
}
return (tList);
}
this is my code when foreach is executed item get 5 values. i want to store the values in model. how i can i store them using linq

Maybe you mean something like this:
public IEnumerable<fields> ConvertTList(List<string[]> rows)
{
return rows.Select(x => StringsToField(x));
}
fields StringsToField(string[] source)
{
return new fields
{
date = source[0],
user = source[1],
campaign = source[2],
adgroup = source[3],
changes = source[4],
};
}

Related

how to return list of list in c#?

I am working on web api.I am getting data from one table.
Data from database
DispatchData dta = new DispatchData();
using (SalesDataContext oSqlData4 = new SalesDataContext())
{
// amount paid -- not paid
var Amount_Paid = (from x in oSqlData4.Finances
where
(x.Order.Customer_ID.Equals("190") ||
x.Order.Customer_ID.Equals("1334"))
where (x.Status == "Not Approved")
select x).ToList();
foreach (var item in Amount_Paid)
{
dta.data = new string[] { item.Order_ID.ToString(), item.ID.ToString() };
}
var json = JsonConvert.SerializeObject(dta);
return json;
}
public class DispatchData
{
public string[] data ;
}
its returning me only one record
{"data":["2508","4684"]}
I want each row in array like this
{"data":[ ["2508","4684"],["2508","4684"],....] }
There's really not enough information in the question for a full answer, but with a few assumptions...
Assuming the SalesDataContext query returns an object, let's call it SalesPerson:
SalesPerson
Name (string)
Title (string)
Location (string)
Id (int)
Date (DateTime)
Sales (decimal)
With the above assumption, you can simply select each property as a string from the query result and throw it into an array:
var myList = Amount_Paid.Select(x =>
new[] {
x.Name,
x.Title,
x.Location,
x.Id.ToString(),
x.Date.ToString(), // add a format as needed
x.Sales.ToString() // add a format as needed
}
).ToArray();
return myList;
If you Really want a List:
var myList = Amount_Paid.Select(x =>
new List<string> {
x.Name,
x.Title,
x.Location,
x.Id.ToString(),
x.Date.ToString(), // add a format as needed
x.Sales.ToString() // add a format as needed
}
).ToList();
return myList;
The result can then be serialized as needed.
Edit
Based on the OP's edit, not much changes with the assumptions above. However, the OP's edit has two errors.
The foreach loop is overwriting dta.data.
The signature of data.data should be string[][], not string[].
Incorrect
public class DispatchData
{
public string[] data ;
}
foreach (var item in Amount_Paid)
{
dta.data = new string[] { item.Order_ID.ToString(), item.ID.ToString() };
}
Corrected
public class DispatchData
{
public string[][] data;
}
# can either predefine the size of the dta.data array,
# or just assign once the property can be materialized.
# Let's use the latter...
dta.data = Amount_Paid.Select(x =>
new[] {
item.Order_ID.ToString(),
item.ID.ToString()
}).ToArray();

How to select specific fields from dynamic list using LINQ

I am trying to get the some specific fields from dynamic object with is actually a list of any class, this class contains various fields out of those fields I want to select some specific fields using LINQ, The fields which I want to select is also passing by the user. Below is the code that I have tried using System.Linq.Dynamic.
using System.Linq;
using System.Text;
using System.Linq.Expressions;
using System.Linq.Dynamic;
using System.Collections;
private void Test_Click(object sender, EventArgs e)
{
List<RateInfo> lst = new List<RateInfo>();
lst.Add(new RateInfo() { id_country = "IND", id_state = 1, rate = 2.3f });
lst.Add(new RateInfo() { id_country = "IND", id_state = 2, rate = 1.1f });
lst.Add(new RateInfo() { id_country = "IND", id_state = 3, rate = 5.2f });
lst.Add(new RateInfo() { id_country = "IND", id_state = 4, rate = 6.5f });
GetDynamicData(lst, new List<string>() { "id_country", "id_state" });
}
private void GetDynamicData(dynamic list, List<string> fetchFields)
{
var data = ((IEnumerable)list).Cast<dynamic>()
.Select(r => new { r }).AsQueryable();
StringBuilder s = new StringBuilder();
//This is for test only.
//It works, the value of "id_state" and "id_state" getting appended
foreach (var item in data)
{
s.Append(item.r.id_state);
s.Append(",");
s.Append(item.r.id_country);
}
//-----------------------------------------------------
//Select the specific field data from dynamic list
StringBuilder fields = new StringBuilder();
fields.Append("new (");
foreach (var fld in fetchFields)
{
fields.Append("r." + fld);
fields.Append(",");
}
fields.Remove(fields.Length - 1, 1);
fields.Append(")");
//This does not work throws error
//"No property or field 'id_country' exists in type 'Object'"
IQueryable iq = data.Select(fields.ToString());
//For test only to check the value of selected fields
foreach (dynamic item in iq)
{
s.Append(item.id_state);
s.Append(",");
s.Append(item.id_country);
}
}
you can hughly simplify your GetDynamicData method both specifying explicit list type (GetDynamicData(IList<RateInfo> list, ...)) and leaving the list item type generic, in order to reuse the method; with this last approach in mind, you can rewrite the GetDynamicData as follows, obtaining the desired output:
private void GetDynamicData<T>(IEnumerable<T> list, List<string> fetchFields)
{
var fields = $"new ({string.Join(",", fetchFields)})";
var res = list.AsQueryable().Select(fields);
//For test only to check the value of selected fields
foreach (dynamic item in res) {
Console.WriteLine(item.id_state);
Console.WriteLine(item.id_country);
}
}
OUTPUT
1
IND
2
IND
3
IND
4
IND
EXPLANATION
I think the difference is that specifying explicitly the type (through generic T or through RateInfo) you force LINQ to know list items'type; if you use dynamic the IQueryable.ElementType of the IQuqryable instance has value System.Object, so the query fails with the error you've experienced.
You should try using generics:
private void GetDynamicData<T>(IEnumerable<T> list, List<string> fetchFields)
{
var data = list.AsQueryable();

How to dynamically GroupBy using Linq

There are several similar sounding posts, but none that do exactly what I want.
Okay, so imagine that I have the following data structure (simplified for this LinqPad example)
public class Row
{
public List<string> Columns { get; set; }
}
public List<Row> Data
=> new List<Row>
{
new Row { Columns = new List<string>{ "A","C","Field3"}},
new Row { Columns = new List<string>{ "A","D","Field3"}},
new Row { Columns = new List<string>{ "A","C","Field3"}},
new Row { Columns = new List<string>{ "B","D","Field3"}},
new Row { Columns = new List<string>{ "B","C","Field3"}},
new Row { Columns = new List<string>{ "B","D","Field3"}},
};
For the property "Data", the user will tell me which column ordinals to GroupBy; they may say "don't group by anything", or they may say "group by Column[1]" or "group by Column[0] and Column[1]".
If I want to group by a single column, I can use:
var groups = Data.GroupBy(d => d.Columns[i]);
And if I want to group by 2 columns, I can use:
var groups = Data.GroupBy(d => new { A = d.Columns[i1], B = d.Columns[i2] });
However, the number of columns is variable (zero -> many); Data could contain hundreds of columns and the user may want to GroupBy dozens of columns.
So the question is, how can I create this GroupBy at runtime (dynamically)?
Thanks
Griff
With that Row data structure what are you asking for is relatively easy.
Start by implementing a custom IEqualityComparer<IEnumerable<string>>:
public class ColumnEqualityComparer : EqualityComparer<IEnumerable<string>>
{
public static readonly ColumnEqualityComparer Instance = new ColumnEqualityComparer();
private ColumnEqualityComparer() { }
public override int GetHashCode(IEnumerable<string> obj)
{
if (obj == null) return 0;
// You can implement better hash function
int hashCode = 0;
foreach (var item in obj)
hashCode ^= item != null ? item.GetHashCode() : 0;
return hashCode;
}
public override bool Equals(IEnumerable<string> x, IEnumerable<string> y)
{
if (x == y) return true;
if (x == null || y == null) return false;
return x.SequenceEqual(y);
}
}
Now you can have a method like this:
public IEnumerable<IGrouping<IEnumerable<string>, Row>> GroupData(IEnumerable<int> columnIndexes = null)
{
if (columnIndexes == null) columnIndexes = Enumerable.Empty<int>();
return Data.GroupBy(r => columnIndexes.Select(c => r.Columns[c]), ColumnEqualityComparer.Instance);
}
Note the grouping Key type is IEnumerable<string> and contains the selected row values specified by the columnIndexes parameter, that's why we needed a custom equality comparer (otherwise they will be compared by reference, which doesn't produce the required behavior).
For instance, to group by columns 0 and 2 you could use something like this:
var result = GroupData(new [] { 0, 2 });
Passing null or empty columnIndexes will effectively produce single group, i.e. no grouping.
you can use a Recursive function for create dynamic lambdaExpression. but you must define columns HardCode in the function.

How to replace duplicated value from a table to "quantity"?

Im trying to make a typical webshop, got everything worked out so far, but I got this following issue: How do I replace duplicate database-value in a List to quantity instead, and list them into ListView? E.g. if I add two of same product into my cart, I want to be able to show quantity instead showing two of same product in the cart-list.
PS: Im listing my results in ListView.
(Form_Load for cart):
using (eShopEntities db = new eShopEntities()){
var list = new List<Product>(db.Products.ToList());
var listFilter = new List<Product>();
foreach (var id in list)
{
foreach (var Sessions in SessionData)//got selected products stored in sessions
{
if (id.ID == Sessions)
{
listFilter.Add(id); //Add all selected products(via session)
}
}
}
int TotSum = 0;
foreach (var sum in listFilter)
{
TotSum = TotSum + sum.Price;
}
cartListView.DataSource = listFilter; cartListView.DataBind();
lblSum.Text = TotSum.ToString();
}
Right now, everything is listed in aspx. But Im not sure how to replace duplicated into quantities from listFilter AND send the quanties-data along with the result from listFilter into cartListWiev togheter.
My Product table(SQL): ID(PK), Name, ImagePath, Price, and CatergoryID(FK)
Thanks
As one of possibilities (not obligatory the best one, but technically it should work) you can change your code like that:
using (eShopEntities db = new eShopEntities()){
IDictionary<long, int> productQuantities = new Dictionary<long, int>(); // supposed your product.ID is of type long
var list = new List<Product>(db.Products.ToList());
var listFilter = new List<Product>();
foreach (var id in list)
{
foreach (var Sessions in SessionData)//got selected products stored in sessions
{
if (id.ID == Sessions)
{
if (!productQuantities.ContainsKey(id.ID)) // new
{
listFilter.Add(id); //Add all selected products(via session)
productQuantities.Add(id.ID, 1)
} // new else {
productQuantities[id.ID]++; // new
}
}
}
}
int TotSum = 0;
foreach (var sum in listFilter)
{
// TotSum = TotSum + sum.Price; // old
sum.Quantity = productQuantities[id.ID]; // supposed your class Product has corresponding property for quantities
TotSum = TotSum + sum.Price * sum.Quantity;
}
cartListView.DataSource = listFilter; cartListView.DataBind();
lblSum.Text = TotSum.ToString();
}

Compare Model to List<string>

I have 2 lists I am trying to compare.
List SelectedPersonCodes; is a just a list of strings (obviously)
List CurrentUserLocations; is a list of LocationId, LocationName pairs.
I need to see if any of the CurrentUserLocation locationIds have a match in the SelectedPersonCOdes list, which is made up of locationIds.
I have put together this:
public JsonResult VerifyDetailAccess(int id)
{
List<UserLocation> CurrentUserLocation = repo.GetUserLocations();
List<string> SelectedPersonLocations = repo.GetTrespassedSiteCodes(id);
bool IsAuth = false;
foreach (var current in CurrentUserLocation)
{
for(var s = 0; s < SelectedPersonLocations.Count(); s++)
{
if(current.LocationCode == SelectedPersonLocations[s])
{
IsAuth = true;
}
}
}
return Json(IsAuth, JsonRequestBehavior.AllowGet);
}
It always comes out false. The problem is the if statement, I am not getting the values in the SelectedPersonLocations. How do I expose those values so I can iterate against them?
I have also tried dual foreach:
foreach (var current in CurrentUserLocation)
{
foreach (var select in SelectedPersonLocations)
{
if(current.LocationCode == select)
{
IsAuth = true;
}
}
This exposes the value in select, but even if current.LocationCode and select are the same, it still skips setting the flag, so IsAuth stays false.

Categories