How to find max value from struct? - c#

public struct nariai
{
public string vardas;
public string pavarde;
public double eurai;
public double centai;
public double suma;
};
static void Main(string[] args)
{
double islaidos;
double surinktiPinigai = 0;
StreamReader failas = new StreamReader("nariai.txt");
string a = failas.ReadLine();
int nariuKiekis = int.Parse(a);
nariai[] narys = new nariai[nariuKiekis];
string[] info = new string[nariuKiekis];
for (int i = 0; i < nariuKiekis; i++)
{
info[i] = failas.ReadLine();
string[] informacija = info[i].Split(' ');
narys[i].vardas = informacija[0];
narys[i].pavarde = informacija[1];
narys[i].eurai = double.Parse(informacija[2]);
narys[i].centai = double.Parse(informacija[3]);
Console.WriteLine("{0} {1} {2} {3}", narys[i].vardas, narys[i].pavarde, narys[i].eurai, narys[i].centai);
}
for (int i = 0; i < nariuKiekis; i++)
{
islaidos = narys[i].eurai * 100 + narys[i].centai;
narys[i].suma = islaidos / 100 * 0.25;
islaidos = narys[i].suma;
Console.WriteLine(narys[i].suma);
surinktiPinigai = surinktiPinigai + islaidos;
}
Console.WriteLine("Surinkti pinigai bendroms išlaidoms: {0} Eurai.", surinktiPinigai);
}
File looks like that:
Command looks like that:
I need to find who has the biggest value in the structure "public double suma" and i need to write first name and last name of it.

What you want is to retrieve from the list the item with the max suma and then you can get it's other properties.
var item = narys.OrderByDescending(i => i.suma).FirstOrDefault();
var name = $"{item?.vardas} {item?.pavarde}";
Notice the use of the ?. operator available since C# 6.0 that verifies item is not null. If by the time you perform this querying you know for sure that collection is not empty then simply:
var item = narys.OrderByDescending(i => i.suma).First();
var name = $"{item.vardas} {item.pavarde}";
You can also use MoreLinq's MaxBy which:
Returns the maximal element of the given sequence, based on the given projection.

You can try using LINQ:
var maxNarys = narys.OrderByDescending(n => n.suma)
.FirstOrDefault();
And then access it's properties like this:
var maxNarvardas = maxNarys.vardas;
EDIT
Also looking at your code more closely:
it seems that you can concat your two loops and add a variables to find max:
var maxSuma = double.MinValue;
var maxIndex = -1;
for (int i = 0; i < nariuKiekis; i++)
{
info[i] = failas.ReadLine();
string[] informacija = info[i].Split(' ');
narys[i].vardas = informacija[0];
narys[i].pavarde = informacija[1];
narys[i].eurai = double.Parse(informacija[2]);
narys[i].centai = double.Parse(informacija[3]);
Console.WriteLine("{0} {1} {2} {3}", narys[i].vardas, narys[i].pavarde, narys[i].eurai, narys[i].centai);
islaidos = narys[i].eurai * 100 + narys[i].centai;
narys[i].suma = islaidos / 100 * 0.25;
islaidos = narys[i].suma;
if(maxSuma < narys[i].suma)
{
maxSuma = narys[i].suma;
maxIndex = i;
}
surinktiPinigai = surinktiPinigai + islaidos;
}
if(maxIndex>=0) Console.WriteLine(narys[maxIndex].suma);

Related

Copying static list to local temp list

Hello I have some static lists, and I have lots of websocket connection and uptading these lists. But in paribuMiktarHesaplama() function, I want to use local temp lists to not change my static lists. But when anything changes on local list , its also effecting my static lists. I didnt any assignment, why its changing and How can I fix ?
static List<decimal> p_btcTlAskPrice = new List<decimal>(new decimal[2]);
static List<decimal> p_btcTlAskQuantity = new List<decimal>(new decimal[2]);
static List<decimal> b_btcUsdtBidPrice = new List<decimal>(new decimal[20]);
static List<decimal> b_btcUsdtBidQuantity = new List<decimal>(new decimal[20]);
/// and more list here...
Static lists
public static (decimal,int,decimal,decimal,decimal) FindMin(decimal paribuPrice, decimal paribuAmount, decimal binancePrice,decimal binanceAmount,decimal usdtTryPrice, decimal usdtTryAmount)
{
decimal paribuTotal,binanceTotal,usdtTotal;
decimal enkucuk;
int enkucukList;
paribuTotal = paribuPrice* paribuAmount/usdtTryPrice;
binanceTotal = binancePrice * binanceAmount;
enkucuk = usdtTryAmount;
usdtTotal = usdtTryAmount;
enkucukList = 3;
if (paribuTotal < enkucuk) {
enkucuk = paribuTotal;
enkucukList = 1;
}
if (binanceTotal < enkucuk) {
enkucuk = binanceTotal;
enkucukList = 2;
}
return (enkucuk, enkucukList,paribuTotal,binanceTotal,usdtTotal);
}
public static void paribuMiktarHesaplama(List<decimal> paribuPrice,List<decimal> paribuAmount,List<decimal> binancePrice,List<decimal> binanceAmount)
{
var i = 0; var j = 0; var k = 0; decimal enKucuk = 0 ; int enKucukList; decimal totalAmount=0; decimal enKucukParibu = 0; decimal enKucukBinance = 0; decimal enKucukUsdt = 0;
var tempParibuAmount = paribuAmount; var tempBinanceAmount = binanceAmount; var tempUsdtTryAmount = b_usdtTryBidQuantity;
var tempParibuPrice = paribuPrice; var tempBinancePrice = binancePrice; var tempUsdtTryPrice = b_usdtTryBidPrice;
while (true)
{
if (tempParibuPrice[i] * paribuFee < tempBinancePrice[j] / binanceFee * tempUsdtTryPrice[k] / binanceFee)
{//en küçük miktarın çıkarılması lazım
var returnTuple = FindMin(tempParibuPrice[i], tempParibuAmount[i], tempBinancePrice[j], tempBinanceAmount[j], tempUsdtTryPrice[k], tempUsdtTryAmount[k]);
enKucuk = returnTuple.Item1;
enKucukList = returnTuple.Item2;
enKucukParibu = returnTuple.Item3;
enKucukBinance = returnTuple.Item4;
enKucukUsdt = returnTuple.Item5;
totalAmount += enKucuk; // dolar cinsinden
if (enKucukList == 1)
{
//paribu
tempBinanceAmount[j] = (enKucukBinance - enKucuk)/binancePrice[j];
tempUsdtTryAmount[k] = (enKucukUsdt - enKucuk);
tempParibuAmount.RemoveAt(0);
tempParibuPrice.RemoveAt(0);
//i++;
}
else if (enKucukList == 2)
{
//binance
tempParibuAmount[i] = (enKucukParibu - enKucuk ) * b_usdtTryBidPrice[k];
tempUsdtTryAmount[k] = (enKucukUsdt - enKucuk);
tempBinanceAmount.RemoveAt(0);
tempBinancePrice.RemoveAt(0);
//j++;
}
else
{
//tether
tempBinanceAmount[j] = (enKucukBinance - enKucuk) / binancePrice[j];
tempParibuAmount[i] = (enKucukParibu - enKucuk) * b_usdtTryBidPrice[k]/paribuPrice[i];
tempUsdtTryAmount.RemoveAt(0);
tempUsdtTryPrice.RemoveAt(0);
//k++;
}
}
else
{
break;
}
}
Console.WriteLine($"alınacak miktar {totalAmount} fiyatlar paribu {paribuPrice[i]} binance {binancePrice[j]} usdt {b_usdtTryBidPrice[k]}");
}
functions
p_btcTlAskPrice[0] = 600;
p_btcTlAskQuantity[0] = 60;
b_btcUsdtBidPrice[0] = 100;
b_btcUsdtBidQuantity[0] = 80;
b_usdtTryBidPrice[0] = 7;
b_usdtTryBidQuantity[0] = 500;
p_btcTlAskPrice[1] = 650;
p_btcTlAskQuantity[1] = 100;
b_btcUsdtBidPrice[1] = 95;
b_btcUsdtBidQuantity[1] = 50;
b_usdtTryBidPrice[1] = 6.8m;
b_usdtTryBidQuantity[1] = 10000;
paribuMiktarHesaplama(p_btcTlAskPrice, p_btcTlAskQuantity, b_btcUsdtBidPrice, b_btcUsdtBidQuantity);
var tempParibuAmount = paribuAmount
is an assignment that takes the reference of the List you passed. What you need to do is to create a copy of the paribuAmount and store that copy instead:
var tempParibuAmount = new List<decimal>(paribuAmount)
Do that instead for every temp list you create

Diff comparison word by word and display changes

Could be marked as duplicated, but I haven't found a propper solution yet.
I need to write a function that compares 2 pieces of text word by word, and prints out the text showing added/deleted/changed words. For example:
StringOriginal = "I am Tim and I am 27 years old"
StringEdited = "I am Kim and I am not that old".
Result: I am Tim Kim and I am 27 years not that old.
Most of the diff algorithms I find tend to compare char by char. this works fine, untill you have a 2 different words on the same index, with mutual chars.
"I am Tim" edited to
"I am Kim"
Results into:
I am TKim
instead of
I am Tim Kim.
Any pointers?
Split by space both StringOriginal and StringEdited. Loop thru each word of StringOriginal comparing it to the same word index from Edited. Every unequal word should be put to a temporary variable and concatenate it to the result only when you get equal word again from the loop. Use StringBuilder in creating the result. Hope this helps
Split both strings by space, join the resulting arrays via Union, then back to string like this:
string[] arr1 = str1.Split(' ');
string[] arr2 = str1.Split(' ');
var merged = arr1.Union(arr2).ToArray<string>();
var mergedString = string.Join(' ', merged);
little bit old fashion, but you can try this.
string StringOriginal = "I am Tim and I am 27 years old";
string StringEdited = "I am Kim and I am not that old";
string[] StringOriginalArray = StringOriginal.Split();
string[] StringEditedArray = StringEdited.Split();
string[] newStringArray = new string[StringOriginalArray.Length + StringEditedArray.Length];
int i = 0;
int io = 0;
int ie = 0;
while (i < newStringArray.Length)
{
if (io < StringOriginalArray.Length)
{
newStringArray[i] = StringOriginalArray[io];
io++;
i++;
}
if (ie < StringEditedArray.Length)
{
newStringArray[i] = StringEditedArray[ie];
ie++;
i++;
}
}
string[] finalArray = new string[newStringArray.Length];
int f = 0;
for (int k = 0; k < newStringArray.Length; k=k+2)
{
finalArray[f++] = newStringArray[k];
if (newStringArray[k] != newStringArray[k+1])
{
finalArray[f++] = newStringArray[k+1];
}
}
Console.WriteLine(String.Join(" ", finalArray));
Output:
"I am Tim Kim and I am 27 not years that old"
been looking for an answer myself to this question.
haven't been able to find a good solution.
came up with the following. but it's not perfect.
public static class DiffEngine
{
private static Regex r = new Regex(#"(?<=[\s])", RegexOptions.Compiled);
public static string Process(ref string TextA, ref string TextB)
{
var A = r.Split(TextA);
var B = r.Split(TextB);
var max = Math.Max(A.Count(), B.Count());
var sbDel = new StringBuilder("<del>");
var sbIns = new StringBuilder("<ins>");
var sbOutput = new StringBuilder();
var aCurr = string.Empty;
var bCurr = string.Empty;
var aNext = string.Empty;
var bNext = string.Empty;
for (int i = 0; i < max; i++)
{
aCurr = (i > A.Count() - 1) ? string.Empty : A[i];
bCurr = (i > B.Count() - 1) ? string.Empty : B[i];
aNext = (i > A.Count() - 2) ? string.Empty : A[i + 1];
bNext = (i > B.Count() - 2) ? string.Empty : B[i + 1];
if (aCurr == bCurr)
{
sbOutput.Append(aCurr);
}
else
{
if (aNext != bNext)
{
sbDel.Append(aCurr);
sbIns.Append(bCurr);
}
else
{
sbDel.Append(aCurr);
sbIns.Append(bCurr);
sbOutput
.Append(sbDel.ToString())
.Append("</del>")
.Append(sbIns.ToString())
.Append("</ins>");
sbDel.Clear().Append("<del>");
sbIns.Clear().Append("<ins>");
}
}
}
A = null;
B = null;
sbDel = null;
sbIns = null;
return sbOutput.ToString();
}
}

Better way for the special concatenation of two strings

I want to concatenate two strings in such a way, that after the first character of the first string, the first character of second string comes, and then the second character of first string comes and then the second character of the second string comes and so on. Best explained by some example cases:
s1="Mark";
s2="Zukerberg"; //Output=> MZaurkkerberg
if:
s1="Zukerberg";
s2="Mark" //Output=> ZMuakrekrberg
if:
s1="Zukerberg";
s2="Zukerberg"; //Output=> ZZuukkeerrbbeerrgg
I've written the following code which gives the expected output but its seems to be a lot of code. Is there any more efficient way for doing this?
public void SpecialConcat(string s1, string s2)
{
string[] concatArray = new string[s1.Length + s2.Length];
int k = 0;
string final = string.Empty;
string superFinal = string.Empty;
for (int i = 0; i < s1.Length; i++)
{
for (int j = 0; j < s2.Length; j++)
{
if (i == j)
{
concatArray[k] = s1[i].ToString() + s2[j].ToString();
final = string.Join("", concatArray);
}
}
k++;
}
if (s1.Length > s2.Length)
{
string subOne = s1.Remove(0, s2.Length);
superFinal = final + subOne;
}
else if (s2.Length > s1.Length)
{
string subTwo = s2.Remove(0, s1.Length);
superFinal = final + subTwo;
}
else
{
superFinal = final;
}
Response.Write(superFinal);
}
}
I have written the same logic in Javascript also, which works fine but again a lot of code.
var s1 = "Mark";
var s2 = "Zukerberg";
var common = string.Concat(s1.Zip(s2, (a, b) => new[]{a, b}).SelectMany(c => c));
var shortestLength = Math.Min(s1.Length, s2.Length);
var result =
common + s1.Substring(shortestLength) + s2.Substring(shortestLength);
var stringBuilder = new StringBuilder();
for (int i = 0; i < Math.Max(s1.Length, s2.Length); i++)
{
if (i < s1.Length)
stringBuilder.Append(s1[i]);
if (i < s2.Length)
stringBuilder.Append(s2[i]);
}
string result = stringBuilder.ToString();
In JavaScript, when working with strings, you are also working with arrays, so it will be easier. Also + will concatenate for you. Replace string indexing with charAt if you want IE7- support.
Here is the fiddle:
http://jsfiddle.net/z6XLh/1
var s1 = "Mark";
var s2 = "ZuckerFace";
var out ='';
var l = s1.length > s2.length ? s1.length : s2.length
for(var i = 0; i < l; i++) {
if(s1[i]) {
out += s1[i];
}
if(s2[i]){
out += s2[i];
}
}
console.log(out);
static string Join(string a, string b)
{
string returnVal = "";
int length = Math.Min(a.Length, b.Length);
for (int i = 0; i < length; i++)
returnVal += "" + a[i] + b[i];
if (a.Length > length)
returnVal += a.Substring(length);
else if(b.Length > length)
returnVal += b.Substring(length);
return returnVal;
}
Could possibly be improved through stringbuilder
Just for the sake of curiosity, here's an unreadable one-liner (which I have nevertheless split over multiple lines ;))
This uses the fact that padding a string to a certain length does nothing if the string is already at least that length. That means padding each string to the length of the other string will have the result of padding out with spaces the shorter one to the length of the longer one.
Then we use .Zip() to concatenate each of the pairs of characters into a string.
Then we call string.Concat(IEnumerable<string>) to concatenate the zipped strings into a single string.
Finally, we remove the extra padding spaces we introduced earlier by using string.Replace().
var result = string.Concat
(
s1.PadRight(s2.Length)
.Zip
(
s2.PadRight(s1.Length),
(a,b)=>string.Concat(a,b)
)
).Replace(" ", null);
On one line [insert Coding Horror icon here]:
var result = string.Concat(s1.PadRight(s2.Length).Zip(s2.PadRight(s1.Length), (a,b)=>string.Concat(a,b))).Replace(" ", null);
Just off the top of my head, this is how I might do it.
var s1Length = s1.Length;
var s2Length = s2.Length;
var count = 0;
var o = "";
while (s1Length + s2Length > 0) {
if (s1Length > 0) {
s1Length--;
o += s1[count];
}
if (s2Length > 0) {
s2Length--;
o += s2[count];
}
count++;
}
Here's another one-liner:
var s1 = "Mark";
var s2 = "Zukerberg";
var result = string.Join("",
Enumerable.Range(0, s1.Length).ToDictionary(x => x * 2, x => s1[x])
.Concat(Enumerable.Range(0, s2.Length).ToDictionary(x => x * 2+1, x => s2[x]))
.OrderBy(d => d.Key).Select(d => d.Value));
Basically, this converts both strings into dictionaries with keys that will get the resulting string to order itself correctly. The Enumerable range is used to associate an index with each letter in the string. When we store the dictionaries, it multiplies the index on s1 by 2, resulting in <0,M>,<2,a>,<4,r>,<6,k>, and multiplies s2 by 2 then adds 1, resulting in <1,Z>,<3,u>,<5,k>, etc.
Once we have these dictionaries, we combine them with the .Concat and sort them with the .OrderBy,which gives us <0,M>,<1,Z>,<2,a>,<3,u>,... Then we just dump them into the final string with the string.join at the beginning.
Ok, this is the *second shortest solution I could come up with:
public string zip(string s1, string s2)
{
return (string.IsNullOrWhiteSpace(s1+s2))
? (s1[0] + "" + s2[0] + zip(s1.Substring(1) + " ", s2.Substring(1) + " ")).Replace(" ", null)
: "";
}
var result = zip("mark","zukerberg");
Whoops! My original shortest was the same as mark's above...so, second shortest i could come up with! I had hoped I could really trim it down with the recursion, but not so much.
var sWordOne = "mark";// ABCDEF
var sWordTwo = "zukerberg";// 123
var result = (sWordOne.Length > sWordTwo.Length) ? zip(sWordOne, sWordTwo) : zip(sWordTwo, sWordOne);
//result = "zmuakrekrberg"
static string zip(string sBiggerWord, string sSmallerWord)
{
if (sBiggerWord.Length < sSmallerWord.Length) return string.Empty;// Invalid
if (sSmallerWord.Length == 0) sSmallerWord = " ";
return string.IsNullOrEmpty(sBiggerWord) ? string.Empty : (sBiggerWord[0] + "" + sSmallerWord[0] + zip(sBiggerWord.Substring(1),sSmallerWord.Substring(1))).Replace(" ","");
}
A simple alternative without Linq witchcraft:
string Merge(string one, string two)
{
var buffer = new char[one.Length + two.Length];
var length = Math.Max(one.Length, two.Length);
var index = 0;
for (var i = 0; i < length; i ++)
{
if (i < one.Length) buffer[index++] = one[i];
if (i < two.Length) buffer[index++] = two[i];
}
return new string(buffer);
}

C# How can I compare two word strings and indicate which parts are different

For example if I have...
string a = "personil";
string b = "personal";
I would like to get...
string c = "person[i]l";
However it is not necessarily a single character. I could be like this too...
string a = "disfuncshunal";
string b = "dysfunctional";
For this case I would want to get...
string c = "d[isfuncshu]nal";
Another example would be... (Notice that the length of both words are different.)
string a = "parralele";
string b = "parallel";
string c = "par[ralele]";
Another example would be...
string a = "ato";
string b = "auto";
string c = "a[]to";
How would I go about doing this?
Edit: The length of the two strings can be different.
Edit: Added additional examples. Credit goes to user Nenad for asking.
I must be very bored today, but I actually made UnitTest that pass all 4 cases (if you did not add some more in the meantime).
Edit: Added 2 edge cases and fix for them.
Edit2: letters that repeat multiple times (and error on those letters)
[Test]
[TestCase("parralele", "parallel", "par[ralele]")]
[TestCase("personil", "personal", "person[i]l")]
[TestCase("disfuncshunal", "dysfunctional", "d[isfuncshu]nal")]
[TestCase("ato", "auto", "a[]to")]
[TestCase("inactioned", "inaction", "inaction[ed]")]
[TestCase("refraction", "fraction", "[re]fraction")]
[TestCase("adiction", "ad[]diction", "ad[]iction")]
public void CompareStringsTest(string attempted, string correct, string expectedResult)
{
int first = -1, last = -1;
string result = null;
int shorterLength = (attempted.Length < correct.Length ? attempted.Length : correct.Length);
// First - [
for (int i = 0; i < shorterLength; i++)
{
if (correct[i] != attempted[i])
{
first = i;
break;
}
}
// Last - ]
var a = correct.Reverse().ToArray();
var b = attempted.Reverse().ToArray();
for (int i = 0; i < shorterLength; i++)
{
if (a[i] != b[i])
{
last = i;
break;
}
}
if (first == -1 && last == -1)
result = attempted;
else
{
var sb = new StringBuilder();
if (first == -1)
first = shorterLength;
if (last == -1)
last = shorterLength;
// If same letter repeats multiple times (ex: addition)
// and error is on that letter, we have to trim trail.
if (first + last > shorterLength)
last = shorterLength - first;
if (first > 0)
sb.Append(attempted.Substring(0, first));
sb.Append("[");
if (last > -1 && last + first < attempted.Length)
sb.Append(attempted.Substring(first, attempted.Length - last - first));
sb.Append("]");
if (last > 0)
sb.Append(attempted.Substring(attempted.Length - last, last));
result = sb.ToString();
}
Assert.AreEqual(expectedResult, result);
}
Have you tried my DiffLib?
With that library, and the following code (running in LINQPad):
void Main()
{
string a = "disfuncshunal";
string b = "dysfunctional";
var diff = new Diff<char>(a, b);
var result = new StringBuilder();
int index1 = 0;
int index2 = 0;
foreach (var part in diff)
{
if (part.Equal)
result.Append(a.Substring(index1, part.Length1));
else
result.Append("[" + a.Substring(index1, part.Length1) + "]");
index1 += part.Length1;
index2 += part.Length2;
}
result.ToString().Dump();
}
You get this output:
d[i]sfunc[shu]nal
To be honest I don't understand what this gives you, as you seem to completely ignore the changed parts in the b string, only dumping the relevant portions of the a string.
Here is a complete and working console application that will work for both examples you gave:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
string a = "disfuncshunal";
string b = "dysfunctional";
StringBuilder sb = new StringBuilder();
for (int i = 0; i < a.Length; i++)
{
if (a[i] != b[i])
{
sb.Append("[");
sb.Append(a[i]);
sb.Append("]");
continue;
}
sb.Append(a[i]);
}
var str = sb.ToString();
var startIndex = str.IndexOf("[");
var endIndex = str.LastIndexOf("]");
var start = str.Substring(0, startIndex + 1);
var mid = str.Substring(startIndex + 1, endIndex - 1);
var end = str.Substring(endIndex);
Console.WriteLine(start + mid.Replace("[", "").Replace("]", "") + end);
}
}
}
it will not work if you want to display more than one entire section of the mismatched word.
You did not specify what to do if the strings were of different lengths, but here is a solution to the problem when the strings are of equal length:
private string Compare(string string1, string string2) {
//This only works if the two strings are the same length..
string output = "";
bool mismatch = false;
for (int i = 0; i < string1.Length; i++) {
char c1 = string1[i];
char c2 = string2[i];
if (c1 == c2) {
if (mismatch) {
output += "]" + c1;
mismatch = false;
} else {
output += c1;
}
} else {
if (mismatch) {
output += c1;
} else {
output += "[" + c1;
mismatch = true;
}
}
}
return output;
}
Not really good approach but as an exercise in using LINQ: task seem to be find matching prefix and suffix for 2 strings, return "prefix + [+ middle of first string + suffix.
So you can match prefix (Zip + TakeWhile(a==b)), than repeat the same for suffix by reversing both strings and reversing result.
var first = "disfuncshunal";
var second = "dysfunctional";
// Prefix
var zipped = first.ToCharArray().Zip(second.ToCharArray(), (f,s)=> new {f,s});
var prefix = string.Join("",
zipped.TakeWhile(c => c.f==c.s).Select(c => c.f));
// Suffix
var zippedReverse = first.ToCharArray().Reverse()
.Zip(second.ToCharArray().Reverse(), (f,s)=> new {f,s});
var suffix = string.Join("",
zippedReverse.TakeWhile(c => c.f==c.s).Reverse().Select(c => c.f));
// Cut and combine.
var middle = first.Substring(prefix.Length,
first.Length - prefix.Length - suffix.Length);
var result = prefix + "[" + middle + "]" + suffix;
Much easier and faster approach is to use 2 for loops (from start to end, and from end to start).

How do i get the numbers from the GetKey back to the List<float>? (Reverse of what i did)

This is the code for the SetKey i loop over the Lists take out the numbers convert to string and put it in to the SetKey now i need to reverse the action using GetKey and put back the numbers to the Lists so eahc List Point_X and Point_Y will have the numbers as before.
string[] xFrames = new string[wocl.Count];
string[] yFrames = new string[wocl.Count];
string X="";
string Y="";
for (int i = 0; i < wocl.Count; i++)
{
X = string.Format("Frame_X_{0} ", i + 1);
Y = string.Format("Frame_Y_{0} ", i + 1);
for (int j = 0; j < wocl[i].Point_X.Count; j++)
{
xFrames[i] += string.Format("{0},", wocl[i].Point_X[j]);
yFrames[i] += string.Format("{0},", wocl[i].Point_Y[j]);
}
string tt = xFrames[i].Trim(",".ToCharArray());
string yy = yFrames[i].Trim(",".ToCharArray());
setting_file.SetKey(X, tt);
setting_file.SetKey(Y, yy);
}
Now tt is a string of number for example 122,33,44,55,121
Now i need to parse the numbers back. Now i need to take the string and parse the numbers and put them back to a float List:
List a = setting_file.GetKey(X);
But X is a key that present a string of numbers not a List of numbers.
This is the code in the OptionsFile of the functions GetKey and SetKey:
/*----------------------------------------------------------
* Function : GetKey
* Description : gets the value of the key.
* Parameters : key
* Return : value of the key if key exist, null if not exist
* --------------------------------------------------------*/
public string GetKey(string key)
{
// string value_of_each_key;
string key_of_each_line;
string line;
int index;
string key_value;
key_value = null;
sr = new StreamReader(Options_File);
while (null != (line = sr.ReadLine()))
{
index = line.IndexOf("=");
// value_of_each_key = line.Substring(index+1);
if (index >= 1)
{
key_of_each_line = line.Substring(0, index);
if (key_of_each_line == key)
{
key_value = line.Substring(key.Length + 1);
}
}
else
{
}
}
sr.Close();
return key_value;
}
/*----------------------------------------------------------
* Function : SetKey
* Description : sets a value to the specified key
* Parameters : key and a value
* Return : none
* --------------------------------------------------------*/
public void SetKey(string key , string value)
{
bool key_was_found_inside_the_loop;
string value_of_each_key;
string key_of_each_line ;
string line;
int index;
key_was_found_inside_the_loop = false;
temp_settings_file = "\\temp_settings_file.txt";
temp_settings_dir = path_exe + #"\temp_settings";
if (!Directory.Exists(temp_settings_dir))
{
Directory.CreateDirectory(temp_settings_dir);
}
sw = new StreamWriter(temp_settings_dir+temp_settings_file);
sr = new StreamReader(Options_File);
while (null != (line = sr.ReadLine()))
{
index = line.IndexOf("=");
key_of_each_line = line.Substring(0, index);
value_of_each_key = line.Substring( index + 1);
// key_value = line.Substring(0,value.Length);
if (key_of_each_line == key)
{
sw.WriteLine(key + " = " + value);
key_was_found_inside_the_loop = true;
}
else
{
sw.WriteLine(key_of_each_line+"="+value_of_each_key);
}
}
if (!key_was_found_inside_the_loop)
{
sw.WriteLine(key + "=" + value);
}
sr.Close();
sw.Close();
File.Delete(Options_File);
File.Move(temp_settings_dir + temp_settings_file, Options_File);
return;
}
What i need is that in the List a it will contain the numbers from the string X
X is like a key the result in SetKey function is a Key = Value
For example : Hello = 122,33,44,55,66 Hello is like the variable X its the key and on the right hand the numbers are the key values.
So now i need to get the key X values and put them into the List
Cant figure out how to do it.
If before i had a List and i loop over it and took out the numbers from the List and created a string of the numbers and put them in the SetKey now i need to use the GetKey and take the numbers and put them back to the List
Edit:
public void Load(string path,string fileName)
{
string X = "";
string t = path + "\\" + fileName;
OptionsFile setting_file = new OptionsFile(t);
for (int i = 0; i <= wocl.Count ; i++)
{
X = string.Format("Frame_X_{0} ", i + 1);
}
string test = setting_file.GetKey(X);
}
Thep roblem is that if im running in the loop on the List wocl so when im running the program this List is count 0 or 1. But in the GetKey in the text file i might have 4 frames or 1 frame i mean how do i know on how much to count for in the loop ?
I tried with the wocl List for the test but now in the string test im getting the numbers of the first Frame_X_1 but thats it.
While in hte file it self it looks like:
Frame_X_1 =332,325,336,334,332,325,333,328,332
Frame_Y_1 =218,217,202,212,211,210,204,202,204
Frame_X_2 =270,325,336,347,321,325,333,328,332
Frame_Y_2 =257,217,202,282,156,210,204,202,204
Frame_X_3 =270,325,336,347,321,336,270,371,332
Frame_Y_3 =257,217,202,282,156,250,199,135,204
I mean when im running the program all the Lists are empty count to 0 and yet i need to retrive each key Frame_X_1 then Frame_Y_1 and so on...And i dont know how many keys there are.
Add this to a static helper class
public static List<T> ToListOf<T>(this IEnumerable enumerable)
{
var list = new List<T>();
foreach (var item in enumerable)
{
list.Add(item.ConvertTo<T>());
}
return list;
}
then: var myFloats = tt.Split(',').ToListOf<float>();
elegant, no? :)
EDIT
I forgot one more extension method:
public static T ConvertTo<T>(this object source)
{
return (T)Convert.ChangeType(source, typeof(T));
}
Suppose you have a string like "123,33.44.55.66" and you know that this string is comma delimited. to retrieve the numbers:
string str = "123,33,44,55,66";
string[] strArray = str.Split(',');
you can then convert the strArray to any type compatible.

Categories