How to get ienumerated element from sister collection - c#

I often use two related collections and want to access the corresponding elements in a foreach loop.
But, there is no ".Index" property, is there a direct way of doing this, WITHOUT incrementing a counter?
public void PrepareData()
{
var lines = ReadAllLines(#"\\tsclient\T\Bbtra\wapData.txt");
var headers = lines[0].Split(',');
var values = lines.Last().Split(',');
foreach(var value in values.Skip(1))
{
string message = "Data: "+headers[value.Index]+' '+value
}
}

You could use Enumerable.Zip and an anonymous type:
string[] names={"Rod", "Jane", "Freddy"}
int[] ages={28,32,26;};
var pairs=names.Zip(ages, (name,age) => new{Name=name, Age=age});
foreach(var pair in pairs)
{
string name=pair.Name;
string age=pair.Age;
}

Yet another variant, use Select overloading with index like
public void PrepareData()
{
var lines = ReadAllLines(#"\\tsclient\T\Bbtra\wapData.txt");
var headers = lines[0].Split(',');
var values = lines.Last().Split(',').Select((el,index)=>new {value=el, index=index});
foreach(var value in values.Skip(1))
{
string message = "Data: "+headers[value.index]+' '+value.value
}
}
depends on data in headers and values, better variant can be
public void PrepareData()
{
var lines = ReadAllLines(#"\\tsclient\T\Bbtra\wapData.txt");
var headers = lines[0].Split(',');
var values = lines.Last().Split(',');
foreach(var item in values.Skip(1).Select((el,index)=>new {value=el, index=index}))
{
string message = "Data: "+headers[item.index]+' '+item.value
}
}

I'm thinking you want a .Zip.
var pairs = headers.Zip(values,
(header, value) => new Tuple<string, string>(header, value));

Do it with IndexOf
var lines = ReadAllLines(#"\\tsclient\T\Bbtra\wapData.txt");
var headers = lines[0].Split(',');
var values = lines.Last().Split(',');
foreach(var value in values.Skip(1))
{
string message = "Data: " + headers[Array.IndexOf(values, value)] + ' ' + value;
}
or maybe with iterators :
var lines = System.IO.File.ReadAllLines(#"\\tsclient\T\Bbtra\wapData.txt");
var headers = lines[0].Split(',');
var values = lines.Last().Split(',');
var e1 = headers.GetEnumerator();
var e2 = values.GetEnumerator();
while(e1.MoveNext() && e2.MoveNext())
{
string message = "Data: " + e1.Current.ToString() + ' ' + e2.Current.ToString();
}

Related

How to append the values to the json filter format using c#

I have a C# method which takes the filter from URI based on the user input search in the format {"serialNumber":null,"deviceType":"Com'X 510"}.
My method also gets the serialNumber from other endpoints.
siteSNresult and partnerSNresult will fetch the external serial numbers from other endpoints.
I want the serialNumber to be appended to the filter which is fetched from the user input. Please find my code below.
public IEnumerable<EtpDevice> GetUpdatableDevices(int tenantId, [FromUri] string filter, string siteId, string partnerId)
{
var result = new List<EtpDevice>();
StringBuilder str = new StringBuilder();
var siteSNresult = "";
StringBuilder partnerSNresult = new StringBuilder();
var connectedUser = this.permissionService.GetConnectedUser();
if (siteId != "null")
{
var siteList = this.feeDataAccess.GetSitesListById(connectedUser.CurrentEnvironment, siteId);
siteSNresult = siteList.Gateways[0].SerialNumber;
}
if (partnerId != "null")
{
var partnerList = this.feeDataAccess.GetPartnerListbyId(connectedUser.CurrentEnvironment, partnerId);
foreach (var item in partnerList)
{
var partnerSN = item.Gateways[0].SerialNumber;
partnerSNresult = str.Append(partnerSN).AppendLine(";");
}
}
var finalFilter = $"{filter}" + ";" + $"{siteSNresult}" + ";" + $"{partnerSNresult}";
for (int offset = 0; result.Count() == 0 || result.Count() == _defaultLimit; offset += result.Count())
{
result = GetDevices(tenantId, offset, _defaultLimit, finalFilter).ToList();
}
return result;
}
Appended values must be in the var finalFilter. finalFilter must look something like this:
{"serialNumber":"RN-DN18184SE000078-046;AB-TEST51000000136-123","deviceType":"Com'X 510"}
How can I do this? Please help me. Thanks in advance.

How can I return result of string Kusto Query from c#

var kusto = string.Format("let MyData = CompanyMydata" +
" | where ID == 'Z123' | top 1 by dateTimeUtc desc");
var reader = client.ExecuteQuery(kusto);
while (reader.Read())
{
//how can i return coming result as list of string or json string?
}
In while loop I can able to return single column value one by one by using
string state = reader.GetString(1); but i want to return complete result instead of one by one column value.
so that i can do JsonConvert.DeserializeObject<T>(resultString); to specific class.
assuming you're using the client libraries mentioned here, you should be able to do something like the following:
static void Main(string[] args)
{
var kcsb = new KustoConnectionStringBuilder("https://help.kusto.windows.net").WithAadUserPromptAuthentication();
var databaseName = "Samples";
using (var queryProvider = KustoClientFactory.CreateCslQueryProvider(kcsb))
{
var clientRequestProperties = new ClientRequestProperties() { ClientRequestId = "Sample;" + Guid.NewGuid() };
var query = "StormEvents | summarize count(), max(EndTime) by State";
var result = queryProvider.ExecuteQuery<MyType>( // focus on this part
databaseName,
query,
clientRequestProperties)
.ToList();
foreach (var row in result)
{
Console.WriteLine($"State = {row.State}, Count = {row.Count}, MaxEndTime = {row.MaxEndTime}");
}
}
}
class MyType
{
public string State;
public long Count;
public DateTime MaxEndTime;
}

Add new value in var type with old value

i want that my variable var repFolderTree hold old value with new value .
foreach (DataRow row in _dt.Rows)
{
string strFolderData = row["ReportFolder"].ToString();
var repFolderTree = crcr.GetAllReportsHierarchical(username, strFolderData);
repFolderTree.FolderName = "All Reports";
uxAllCatalogHierarchical.Text = string.Format("<div class=\"hierarchicalCatalog\">{0}</div>", HierarchicalCatalogView(repFolderTree, 0, showFolder));
}
public CrissCrossLib.Hierarchical.CrcReportFolder GetAllReportsHierarchical(string username,string path)
{
var hierItems = GetAllReportsHierarchicalNoCache(username, path);
m_cacheManager.AllReportsHierarchicalCacheByUsername.Add(username, hierItems);
return hierItems;
}
private string HierarchicalCatalogView(CrcReportFolder rootFolder, int level, string showFolder)
{
_dt = _ssrsDAC.GetReportListByUser(Convert.ToInt32(Session["LoginID"]));
StringBuilder sb = new StringBuilder();
sb.Append("<div class=\"folderBox\">");
string scrollTo = "";
if (PathMatch(showFolder, rootFolder.Path))
scrollTo = " scrollToFolder";
sb.AppendFormat("<div class=\"folderName{1}\">{0}</div>", rootFolder.FolderName, scrollTo);
string show = "none";
if (level == 0 || PathContains(showFolder, rootFolder.Path))
show = "block";
sb.AppendFormat("<div class=\"folderChildren\" style=\"display:{0}\">", show);
foreach (CrcReportFolder subFolderLoop in rootFolder.SubFolders)
sb.Append(HierarchicalCatalogView(subFolderLoop, level + 1, showFolder));
foreach (CrcReportItem itemLoop in rootFolder.Reports)
{
string str = itemLoop.DisplayName;
DataRow[] foundAuthors = _dt.Select("ReportName = '" + str + "'");
if (foundAuthors.Length != 0)
{
sb.Append("<div class=\"reportRow\">");
sb.AppendFormat("<a class=\"reportLink vanillaHover\" href=\"Report.aspx?path={0}\" >{1}</a>",
Server.UrlEncode(itemLoop.ReportPath), itemLoop.DisplayName);
if (!string.IsNullOrEmpty(itemLoop.ShortDescription))
sb.AppendFormat("<div class=\"reportInfo\">{0}</div>", itemLoop.ShortDescription);
sb.Append("<div class=\"clear\"></div></div>");
}
}
sb.Append("</div></div>");
return sb.ToString();
}
i have a control where i am listing all the value that i am getting from
var repFolderTree = crcr.GetAllReportsHierarchical(username, strFolderData);
so every time loop after that i lost the last value and contain the current value. so i want that i can get all the value after the loop and bind on this control that i am doing in this this line of code
uxAllCatalogHierarchical.Text = string.Format("<div class=\"hierarchicalCatalog\">{0}</div>", HierarchicalCatalogView(repFolderTree, 0, showFolder));
i think my code make some scene for you .
you can use List or Collection to store all the values , with Add operation to add the var value.
List<object> repFolderTree = new List<object>();
foreach (DataRow row in _dt.Rows)
{
string strFolderData = row["ReportFolder"].ToString();
var repFolderTree = crcr.GetAllReportsHierarchical(username, strFolderData);
repFolderTree .Add(repFolderTree );
repFolderTree.FolderName = "All Reports";
uxAllCatalogHierarchical.Text = string.Format("<div class=\"hierarchicalCatalog\">{0}</div>", HierarchicalCatalogView(repFolderTree, 0, showFolder));
}

error Object reference not set to an instance of an object when check Facebook Like?

I had error
Object reference not set to an instance of an object
at:
string[] sB64String = payload.Split('.');
When check if user like the my Facebook page, my code-
protected void Page_Load(object sender, EventArgs e)
{
pageLike();
}
public bool ValidateSignedRequest()
{
string facebooksecret =
System.Configuration.ConfigurationManager.AppSettings["FacebookSecret"];
var VALID_SIGNED_REQUEST = Request.Form["signed_request"];
string applicationSecret = facebooksecret;
string[] signedRequest = VALID_SIGNED_REQUEST.Split('.');
string expectedSignature = signedRequest[0];
string payload = signedRequest[1];
// Attempt to get same hash
var Hmac = SignWithHmac(UTF8Encoding.UTF8.GetBytes(payload), UTF8Encoding.UTF8.GetBytes(applicationSecret));
var HmacBase64 = ToUrlBase64String(Hmac);
return (HmacBase64 == expectedSignature);
}
private string ToUrlBase64String(byte[] Input)
{
return Convert.ToBase64String(Input).Replace("=", String.Empty)
.Replace('+', '-')
.Replace('/', '_');
}
private byte[] SignWithHmac(byte[] dataToSign, byte[] keyBody)
{
using (var hmacAlgorithm = new HMACSHA256(keyBody))
{
hmacAlgorithm.ComputeHash(dataToSign);
return hmacAlgorithm.Hash;
}
}
public Dictionary<string, string> DecodePayload(string payload)
{
//Remove the bad part of signed_request
//Begin
string[] sB64String = payload.Split('.');
payload = payload.Replace((sB64String[0] + "."), string.Empty);
//End
var encoding = new UTF8Encoding();
var decodedJson = payload.Replace("=", string.Empty).Replace('-', '+').Replace('_', '/');
var base64JsonArray = Convert.FromBase64String(decodedJson.PadRight(decodedJson.Length + (4 - decodedJson.Length % 4) % 4, '='));
var json = encoding.GetString(base64JsonArray);
var jObject = JObject.Parse(json);
var parameters = new Dictionary<string, string>();
parameters.Add("page", ((bool)jObject["page"]["liked"]).ToString());
parameters.Add("admin", ((bool)jObject["page"]["admin"]).ToString());
return parameters;
}
protected void pageLike()
{
string pageLiked = string.Empty;
var signed_request = Request.Form["signed_request"];
var json = DecodePayload(signed_request);
foreach (KeyValuePair<string, string> objKVP in json)
{
//Note You can also see if a user is an admin by replacing the objKVP.Key with admin
if (objKVP.Key == "page" && objKVP.Value == "True")
{
Response.Redirect("https://facebookapp.elarabygroup.com/instruction.aspx");
//litJson.Text += objKVP.Key + " - " + objKVP.Value + "<br />";
}
}
}
I can't see anything fundamentally wrong with your code, what I suspect is happening is the request form variable is null i.e.
var signed_request = Request.Form["signed_request"];
the payload variable is being set to a null or empty string. I'd check this and make sure the value is what you expect.
A good idea here is to add a guard clause in DecodePayload to make sure the payload variable has a value before calling the Split method.
e.g.
if (string.IsNullOrEmpty(payload))
throw new ArgumentNullException();

C# Groupby Linq and foreach

I need a more efficient way of producing multiple files from my data group.
Im using a List<MyObject> type and my object has some public properties in which I need to group the data by.
I have heard of Linq and it sounds like something I could use. However Im not sure how to go about it.
I need to produce a text file for each STATE, so grouping all the MyObjects (people) by state, then running a foreach look on them to build the TEXT file.
void Main()
{
List<MyObject> lst = new List<MyObject>();
lst.Add(new MyObject{ name = "bill", state = "nsw", url = "microsoft.com"});
lst.Add(new MyObject{ name = "ted", state = "vic", url = "apple.com"});
lst.Add(new MyObject{ name = "jesse", state = "nsw", url = "google.com"});
lst.Add(new MyObject{ name = "james", state = "qld", url = "toshiba.com"});
string builder = "";
foreach (MyObject item in myObjects) {
builder += item.name + "\r\n";
builder += item.url + "\r\n" + "\r\n\r\n";
}
and out to the `StreamWriter` will be the filenames by state.
In total for the above data I need 3 files;
-nsw.txt
-vic.txt
-qld.txt
Something like this, perhaps?
var groups = lst.GroupBy(x => x.state);
foreach (var group in groups)
{
using (var f = new StreamWriter(group.Key + ".txt"))
{
foreach (var item in group)
{
f.WriteLine(item.name);
f.WriteLine(item.url);
}
}
}
You def. could use LINQ here.
lst.GroupBy(r=> r.state).ToList().ForEach(r=> {
//state= r.Key
//
foreach (var v in r)
{
}
});
The thing about linq. If you want to know how to do something in it. Think "how would I do this in SQL". The keywords are for the most part the same.
You can actually produce entire content with LINQ:
var entryFormat = "{1}{0}{2}{0}{0}{0}";
var groupsToPrint = lst
.GroupBy(p => p.state)
.Select(g => new
{
State = g.Key,
// produce file content on-the-fly from group entries
Content = string.Join("", g.Select(v => string.Format(entryFormat,
Environment.NewLine, v.name, v.url)))
});
var fileNameFormat = "{0}.txt";
foreach (var entry in groupsToPrint)
{
var fileName = string.Format(fileNameFormat, entry.State);
File.WriteAllText(fileName, entry.Content);
}
Something like...
string builderNsw = "";
foreach (MyObject item in lst.Where(o=>o.state == 'nsw')) {
builderNsw += item.name + "\r\n";
builderNsw += item.url + "\r\n" + "\r\n\r\n";
}
...but there are probably many ways to achieve this.
Same as Above - Iterating through groups by group, can get group name also
int itemCounter = 1;
IEnumerable<DataRow> sequence = Datatables.AsEnumerable();
var GroupedData = from d in sequence group d by d["panelName"]; // GroupedData is now of type IEnumerable<IGrouping<int, Document>>
foreach (var GroupList in GroupedData) // GroupList = "document group", of type IGrouping<int, Document>
{
bool chk = false;
foreach (var Item in GroupList)
{
if (chk == false) // means when header is not inserted
{
var groupName = "Panel Name : " + Item["panelName"].ToString();
chk = true;
}
var count = itemCounter.ToString();
var itemRef = Item["reference"].ToString();
itemCounter++;
}
}

Categories