Trim whitespace from DataTable cells with Linq - linq

This piece of code works to trim all spaces in each datacell of each datarow.
How can I get this code:
var dataRows = dataTable.AsEnumerable();
foreach (var row in dataRows)
{
var cellList = row.ItemArray.ToList();
row.ItemArray = cellList.Select(x => x.ToString().Trim()).ToArray();
}
into one line of code so I don't have to loop through each row? Something like this but it doesn't work:
dataTable.AsEnumerable().Select(y => y.ItemArray.ToList()).Select(x => x.ToString().Trim());

If you love LINQish stype:
dataTable.AsEnumerable().ToList()
.ForEach(row =>
{
var cellList = row.ItemArray.ToList();
row.ItemArray = cellList.Select(x => x.ToString().Trim()).ToArray();
});

With linq you can't change item values finally you should run for loop (or foreach) to change fields value.

for example
var iq = obj from dataTable.asEnumerable() select new{
PersonName = a.Field<string>("PersonName"),
PersonID = a.Field<decimal>("PersonID"),
ParticipantString = a.Field<string>("DisplayString"),
PersonUserName = d.Field<string>("UserName")
}

Related

Load multipe sharepoint list item fields in one Go using CSOM c#

***ctx.Load(listItemCollection,
eachItem => eachItem.Include(
item => item,
item => item["Column1"],
item => item["Column2"]
));***
i have list of fields in a array of string instead of column1 and column2, how can i pass it through in include linq, not able to create proper lambda on runtime. i tried following ways but couldn't get success. Static befor loops works but thw fields added in loop fails as it doesn't evaluate string value in loop
***Expression<Func<ListItem, object>>[] paramss = new
Expression<Func<ListItem, object>>[length];
paramss[0] = x => x.ContentType;
paramss[1] = x => x["Title"];
count = 2;
foreach (string item in solConnDefModel.Columns)
{ paramss[count] = x => x[item];
count++;
}***
Please take a reference of below code:
List dlist = context.Web.Lists.GetByTitle("listname");
context.Load(dlist);
context.ExecuteQuery();
string[] fieldNames = { "Id", "Title", "num", "mStartDate" };
// Create the expression used to define the fields to be included
List<Expression<Func<ListItemCollection, object>>> fieldsToBeIncluded = new List<Expression<Func<ListItemCollection, object>>>();
foreach (string s in fieldNames)
{
fieldsToBeIncluded.Add(items => items.Include(item => item[s]));
}
// Initialize the collection of list items
var listItems = dlist.GetItems(new CamlQuery());
context.Load(listItems, fieldsToBeIncluded.ToArray());
context.ExecuteQuery();
You can hover on load method to see what type parameter it requires, then generate a corresponding one and pass it.
i have to create lambda expression at runtime. following code i was able to get expected value
Expression<Func<ListItem, object>>[] paramss = new Expression<Func<ListItem, object>>[length];
foreach (string item in Columns)
{
if (item.ToLower() != "contenttype")
{
ParameterExpression parameter = Expression.Parameter(typeof(ListItem), "x");
var propertyInfo = typeof(ListItem).GetMethod("get_Item");
var arguments = new List<Expression> { Expression.Constant(item) };
var expression = Expression.Call(parameter, propertyInfo, arguments);
var lambda = Expression.Lambda<Func<ListItem, object>>(expression, parameter);
paramss[count] = lambda;
}
else
{
paramss[count] = x => x.ContentType;
}
count++;
}

What's the equivalent of GROUP INTO in Linq extension method?

This is how I'm filtering and grouping transTasks.
var transTasks = from t in taskData
where t.RangeName == rName
group t by t.CultureID into g
select new { language = g.Key, tasks = g };
Now I've a new requirement. Depending on the conditions, I'may filter by RangeName or by TaskOrderId.
That's why I've transformed the above Linq code to the following;
var transTasks = taskData
.Where(predicate)
.GroupBy(???)
.Select(???);
I've researched but I can't still find the equivalent of group into for the extension method. I need to group those transTasks because there is a loop inside another loop.
Thanks for helping
GroupBy is the equivalent , and it seems you have figured it out, your query in Method Syntax would be:
var transTrasks = taskData.Where(t => t.RangeName == rName)
.GroupBy(t => t.CultureID)
.Select(g => new { language = g.Key, tasks = g });
As a side note, Any LINQ query in query expression compiles to Method Syntax.
var transTasks = taskData
.Where(predicate)
.GroupBy(t => t.CultureID)
.Select(g => new { language = g.Key, tasks = g });

Linq GroupBy to alter list

I have a list of items in an IList<>.Each listitem has a date and a few other fields.
I need to order the list by date and then change the list to only show a date for the first item and effectively set the date field to null for the other items if the date is repeated.
Example:
12/01/2012 500
12/01/2012 700
15/02/2012 900
15/02/2012 1100
27/05/2012 2000
Desired Result:
12/01/2012 500
null 700
15/02/2012 900
null 1100
27/05/2012 2000
Is this possible with the linq group by and order by?
Thanks
LINQ operators are not supposed to change the underlying data. You'd better use regular foreach if you're going to modify the data.
This should probably work:
var groups = items.GroupBy(x => x.Date).ToArray();
foreach (var group in groups)
{
foreach (var item in group.Skip(1)) item.Date = null;
}
I would avoid using such a construction since you'll have to double-check that GroupBy preserves order. Instead I would use something like this:
var sortedItems = items.OrderBy(x => x.Date);
var lastVisitedDate = (DateTime?) null;
foreach (var item in sortedItems)
if (Equals(item.Date, lastVisitedDate)) item.Date = null;
else lastVisitedDate = item.Date;
This should work:
var list = new List<DateItem>();
// Initialization ...
var dups = list.Select((Item,Index) => new{ Item,Index })
.GroupBy(x => x.Item.Date)
.Where(g => g.Count() > 1);
foreach(var dup in dups)
{
foreach (var nullable in dup.OrderBy(x => x.Item.Date).Skip(1))
{
list[nullable.Index].Date = null;
}
}
Assuming your class looks similar to this:
class DateItem {
public DateTime? Date;
public int OtherField;
}
Edit: Here's a working demo: http://ideone.com/cVL4G
One way is to use LINQ to get all of the followers and then set their dates to null in a loop:
// Use ToList() to make sortedItems non-lazy so it won't get ordered each time it's called.
var sortedItems = items.OrderBy(x => x.Date).ToList();
var followers = sortedItems.GroupBy(item => item.Date)
.SelectMany(group => group.Skip(1));
foreach (var follower in followers)
{
follower.Date = null;
}
// Now you can use sortedItems.
Or if you prefer the query syntax:
var followers = from item in sortedItems
group item by item.Date into grp
from follower in grp.Skip(1)
select follower;

Linq to CSV select by column

If I have the following (sample) text file;
year,2008,2009,2010
income,1000,1500,2000
dividends,100,200,300
net profit,1100,1700,2300
expenses,500,600,500
profit,600,1100,1800
Is there a way in Linq that I can select the expenses for 2010 only?
So far I have the following which gets me all the data;
var data = File.ReadAllLines(fileName)
.Select(
l => {
var split = l.CsvSplit();
return split;
}
);
foreach (var item in data)
Console.WriteLine("{0}: ${1}", item[0], item[1]);
If you know it's always the 3rd value column, then
// the expenses row
var query = data.Single(d => d[0] == "expenses");
// the third column
return query[3];
and if you don't, then
var columnNumber = Array.IndexOf(data.First(), "2010");
return query[columnNumber];
See LINQtoCSV, its a library that does all this for you. I've used it, and it works like a charm.
http://www.codeproject.com/KB/linq/LINQtoCSV.aspx

How can I convert a DataTable to an IEnumerable<Dictionary<string, object>>?

I'd like to convert a DataTable to an IEnumerable<> of Dictionary<string, object>. I tried the following LINQ query,
from DataRow row in ds.Tables[0].AsEnumerable()
let rowDictionary = new Dictionary<string, object>()
from DataColumn column in row.Table.Columns.Cast<DataColumn>()
select rowDictionary.Add(column.ColumnName, row[column]).ToArray();
but I get the following error:
error CS1943: An expression of type
'System.Collections.Generic.IEnumerable<System.Data.DataColumn>' is not
allowed in a subsequent from clause in a query expression with source type
'System.Data.EnumerableRowCollection<AnonymousType#1>'. Type inference
failed in the call to 'SelectMany'.
I know I can brute-force this with a loop, but it seems like something I should be able to do in LINQ. Thanks in advance for any help!
I assume that what you want is a Dictionary for each row mapping column to value:
var dt = new DataTable();
var columns = dt.Columns.Cast<DataColumn>();
dt.AsEnumerable().Select(dataRow => columns.Select(column =>
new { Column = column.ColumnName, Value = dataRow[column] })
.ToDictionary(data => data.Column, data => data.Value));
Here is a way I do it in the Linq format
var registerdataVerify = (from o in dt.AsEnumerable()
select new
{
DataDef =o["shortName"].ToString(),
Value = Convert.ToInt32(o["valueDec"])
}).ToDictionary(n => n.DataDef, n => n.Value);
Why not something simpler since you have linq?
var dt = new DataTable();
var columnIndex = 0;
var columnName = "UserID";
var Dict = dt.AsEnumerable().ToDictionary( _
row => row(columnName), _
row => row(columnIndex));
It becomes even easier if you're working with strongly-typed datasets:
var dt = new dsData.UsersDataTable();
var Dict = dt.ToDictionary(dr => dr.UserName, dr => dr.UserID);

Resources