Extract key value from a string Using Linq - linq

There is a scenario in which I am sending an HTTP request and getting this response String from the server.
submitstatus: 0
smsid: 255242179159525376
var streamResponse = newStreamReader(response.GetResponseStream()).ReadToEnd().ToString();
I want to extract the key values by using LINQ. New to LINQ any suggestions.

I am using output string to simulate the result
string output = #"submitstatus: 0
smsid: 255242179159525376";
// you can use regex to match the key/value
// what comes before `:` will be the key and after the value
var matches = Regex.Matches(output, #"(?<Key>\w+):\s(?<Value>[^\n]+)");
// for each match, select the `Key` match as a Key for the dictionary and
// `Value` match as the value
var d = matches.OfType<Match>()
.ToDictionary(k => k.Groups["Key"].Value, v => v.Groups["Value"].Value);
So you will have a Dictionary<string, string> with keys and values.
Using Split method
var keysValues = output.Split(new string[] { ":", "\r\n" },
StringSplitOptions.RemoveEmptyEntries);
Dictionary<string, string> d = new Dictionary<string, string>();
for (int i = 0; i < keysValues.Length; i += 2)
{
d.Add(keysValues[i], keysValues[i + 1]);
}
Trying to use purely Linq
var keysValues = output.Split(new string[] { ":", "\r\n" },
StringSplitOptions.RemoveEmptyEntries);
var keys = keysValues.Where((o, i) => (i & 1) == 0);
var values = keysValues.Where((o, i) => (i & 1) != 0);
var dictionary = keys.Zip(values, (k, v) => new { k, v })
.ToDictionary(o => o.k, o => o.v);

Why dont you use regex? Smth like:
(?<=submitstatus:\s)\d+
for submitstatus
and
(?<=smsid:\s)\d+
for smsid

Related

Convert non typical json string to JSON

I'm fetching from a random API url and I'm getting a response like this one:
"key='jio3298', age=24, key='oijf032', age=62". How can I turn this non-json string into a list of JSON objects (i.e [{'key': 'jio3298', age: 24}, {'key':'oijf032', 'age':62}]) in an efficient way using JavaScript? I did get this code problem in an interview (one of the part of the problem. I needed that list to loop and filter based on a condition) and it seems my answer was at the very least slow.
you should use
String.prototype.split()
to create an array and then loop on this arry and create pears of key and value.
here an expmple:
const parser = (input) => {
input = input.split(",");
let keyAgeList = [],
output = [];
for (let i of input) {
i = i.replace("'", "");
i = i.replace(" ", "");
i = i.split("=");
if (i[0] === "key") {
keyAgeList[0] = i[1];
} else {
keyAgeList[1] = i[1];
}
if (keyAgeList.length > 1) {
let x = {
key: keyAgeList[0].replace("'", ""),
age: keyAgeList[1].replace("'", ""),
};
output.push(x);
keyAgeList = [];
}
}
console.log(JSON.stringify(output))
return JSON.stringify(output);
};
parser("key='jio3298', age=24, key='oijf032', age=62")

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++;
}

linq query for update more than one record

I have a table named industries. In this my fields are
workfor_id,
workfor_usr_id,
workfor_industry_id.
With the same values of workfor_id, I have different workfor_industry_id's.
foreach (var k in us){
var ind = dbContext.industries.Where(i => i.workfor_id ==
k.id).Select(i => i).FirstOrDefault();
string ind2 = k.industry;
var industryParts = ind2.Split(',');
var o = (industryParts.Length);
for (c = 0; c < o; c++){
ind.workfor_id = Convert.ToInt16(k.id);
ind.workfor_industry_id = Convert.ToInt16(k.industryid); }
}
To update workfor_industry_id field I have implemented inner loop inside the foreach loop to get the values of workfor_industry_id's.here same record is over loading with different workfor_industry_id's.
can you tell me how to implement this.
UPDATED
This update adds a little more error checking and assumes that -1 is never a valid value for industry_id
short GetShort(string value) {
short returnValue;
value = (value ?? string.Empty).Replace("\"",null);
return short.TryParse(value, out returnValue) ? returnValue : (short)-1;
}
foreach (var k in us){
var id=Convert.ToInt16(k.id);
var toRemove=from i in dbContext.industries
where i.workfor_id == k.id
select i;
var toAdd = from x in (k.industry ?? string.Empty).Split(',')
select new Industry {
workfor_id=id,
workfor_industry_id=GetShort(x)
};
dbContext.industries.DeleteAllOnSubmit(toRemove);
dbContext.industries.InsertAllOnSubmit(toAdd.Where(x=>x.workfor_industry_id != -1));
}
dbContext.SubmitChanges();

Linq PredicateBuilder

public static IQueryable<SearchProfile> FilterData(string Filter, Repository<SearchProfileContext> dc)
{
IQueryable<SearchProfile> data = null;
var predicate = PredicateBuilder.True<SearchProfile>();
Filter = ExcludedParam(Filter);
if (!string.IsNullOrEmpty(Filter))`enter code here`
{
var stringToSplit = Filter;`enter code here`
List<string[]> arrays = new List<string[]>();
var primeArray = stringToSplit.Split('|');
for (int i = 0; i < primeArray.Length; i++)
{
string first = primeArray[i];
if (first.Contains("chkOrientation") == true)
{
string[] Array = first.Replace("chkOrientation=", "").Split(',');
predicate = predicate.And(a => Array.Contains(a.OrientaionID.ToString()));
}
if (first.Contains("chkProfession") == true)
{
string[] Array = first.Replace("chkProfession=", "").Split(',');
**predicate = predicate.And(a => Array.Contains(SqlFunctions.StringConvert((Double)a.ProfessionID)));**
}
}
data = dc.Select<SearchProfile>().Where(predicate).Distinct();
return data;
}
data = (from a in dc.Select<SearchProfile>().Where(a => a.PersonID > 0) select a).Distinct();
return data;
}
When I ran my program, I got this nasty error below:
LINQ to Entities does not recognize the method Int32 ToInteger(System.Object) method, and this method cannot be translated into a store expression.
then,I used SqlFunctions.StringConvert to make it work but the SQL LINQ generated was not evaluating. This is the sample output (it is comparing '1' and '2' instead of 1 and 2)**
Why are you casting a.ProfessionID to double? What type is a.ProfessionID of?
I think there is implicit conversion to integer, which causes calling the ToInteger method.
And why don't you convert items in Array to integer in the first place, and then use Array of ints in the query?

Dynamic Linq to Datatable Derived Field

Is it possible to use Dynamic Linq to run a query similar to:
Select a, b, a + b as c
from MyDataTable
I have an application where the user can enter SQL statements, the results of these statements are then assigned to a DataTable. There is also the option to derive a field based on other fields. (e.g. user can say field C = a + b, or field D = A*B+10 etc).
Ideally I would like to do something similar to:
string myCalc = "Convert.ToDouble(r.ItemArray[14])+Convert.ToDouble(r.ItemArray[45])";
var parameters = from r in dt.AsEnumerable()
select (myCalc);
What I want to do in this example is add the value of column 14 to column 45 and return it. It's up to the user to decide what expression to use so the text in the select needs to be from a string, I cannot hard code the expression. The string myCalc is purely for demonstration purposes.
You could do that using a Dictionary, and a DataReader and Dynamic Queries. Here is an example based in part in Rob Connery's Massive ORM RecordToExpando:
void Main()
{
string connString = "your connection string";
System.Data.SqlClient.SqlConnection conn = new SqlConnection(connString);
string statement = "SUM = EstimatedEffort + OriginalEstimate, Original = OriginalEstimate";
// Note: You should parse the statement so it doesn't have any updates or inserts in it.
string sql = "SELECT " + statement +" FROM Activities";
List<IDictionary<string, object>> results = new List<IDictionary<string, object>>();
conn.Open();
using(conn)
{
var cmd = new SqlCommand(sql, conn);
var reader = cmd.ExecuteReader();
while (reader.Read())
{
var dic = new Dictionary<string, object>();
for (int i = 0; i < reader.FieldCount; i++)
{
dic.Add(
reader.GetName(i),
DBNull.Value.Equals(reader[i]) ? null : reader[i]);
}
results.Add(dic);
}
}
foreach (var dicRow in results)
{
foreach (string key in dicRow.Keys)
{
Console.Write("Key: " + key + " Value: " + dicRow[key]);
}
Console.WriteLine();
}
}
Something like this:
void Main()
{
var dataTable = new DataTable();
dataTable.Columns.Add("a", typeof(double));
dataTable.Columns.Add("b", typeof(double));
dataTable.Rows.Add(new object[] { 10, 20 });
dataTable.Rows.Add(new object[] { 30, 40 });
string myCalc = "Convert.ToDouble(ItemArray[0]) + Convert.ToDouble(ItemArray[1])";
var query = dataTable.AsEnumerable().AsQueryable();
var result = query.Select(myCalc);
foreach (Double c in result)
{
System.Console.WriteLine(c);
}
}

Resources