String comparison with foreach loop. The expected output is "Facebook" - c#

How can we compare two elements in a string and display the most repeated value using the foreach loop?
class Program
{
static void Main(string[] args)
{
string[] values = { "Facebook", "Google", "Facebook" };
foreach (var value in values)
{
// need to comparing the elements in the array
Console.WriteLine(value); /* print the repeated value*/
}
}
}

You could do this pretty easily with LINQ
var mostRepeatedValue = values
.GroupBy(v => v)
.OrderByDescending(gp => gp.Count())
.Select(g => g.Key).FirstOrDefault();

You can try below Code
Dictionary<string, int> stringOccurDict = new Dictionary<string, int>();
string[] values = { "Facebook", "Google", "Facebook" };
foreach(string x in values)
{
if (!stringOccurDict .ContainsKey(x))
stringOccur.Add(x, values.Count(c => values.Contains(c)));
});
string repeatedString = stringOccur.Where(x => x.Value == stringOccur.Values.Max()).FirstOrDefault().Key;
Output
Facebook
You can also get count by using .Value

Related

Find indexes of foreach Tuple List Item equals to given Item

I want to find indexes of foreach Item1 of Tuple List values equals to given string "png".
But I couldn't find what is the right foreach condition was to search for it. Any help would be nice..
List<Tuple<string, string>> fileConverterList = new List<Tuple<string, string>>()
{
Tuple.Create("png","jpg"),
Tuple.Create("jpg","bmp"),
Tuple.Create("png","bmp")
};
string = "png";
foreach (int i in /* fileConverterList condition */)
{
// Provided conditions must be: i = 0 and i = 2. That means;
// fileConverterList[0].Item1 equals to "png" and
// fileConverterList[2].Item1 equals to "png"
}
You can use LINQ to find all the indexes like this:
var indexes = myTuples.Select((t, i) => new { t, i })
.Where(x => x.t.Item1 == "png")
.Select(y => y.i);
Here it is in a demo console app:
static void Main(string[] args)
{
var myTuples = new List<Tuple<string, string>>
{
new Tuple<string, string>("png", "jpg"),
new Tuple<string, string>("jpg", "bmp"),
new Tuple<string, string>("png", "bmp")
};
var indexes = myTuples.Select((t, i) => new { t, i })
.Where(x => x.t.Item1 == "png")
.Select(y => y.i);
Console.WriteLine("Indexes:");
foreach (var index in indexes)
{
Console.WriteLine("Index: " + index);
}
Console.ReadLine();
}
Results:

c# read lines and store values in dictionaries

I want to read a csv file and store the values in a correct way in dictionaries.
using (var reader = new StreamReader(#"CSV_testdaten.csv"))
{
while (!reader.EndOfStream)
{
string new_line;
while ((new_line = reader.ReadLine()) != null)
{
var values = new_line.Split(",");
g.add_vertex(values[0], new Dictionary<string, int>() { { values[1], Int32.Parse(values[2]) } });
}
}
}
the add_vertex function looks like this:
Dictionary<string, Dictionary<string, int>> vertices = new Dictionary<string, Dictionary<string, int>>();
public void add_vertex(string name, Dictionary<string, int> edges)
{
vertices[name] = edges;
}
The csv file looks like this:
there are multiple lines with the same values[0] (e.g. values[0] is "0") and instead of overwriting the existing dictionary, it should be added to the dictionary which already exists with values[0] = 0. like this:
g.add_vertex("0", new Dictionary<string, int>() { { "1", 731 } ,
{ "2", 1623 } , { "3" , 1813 } , { "4" , 2286 } , { "5" , 2358 } ,
{ "6" , 1 } , ... });
I want to add all values which have the same ID (in the first column of the csv file) to one dictionary with this ID. But I'm not sure how to do this. Can anybody help?
When we have complex data and we want to query them, Linq can be very helpful:
var records = File
.ReadLines(#"CSV_testdaten.csv")
.Where(line => !string.IsNullOrWhiteSpace(line)) // to be on the safe side
.Select(line => line.Split(','))
.Select(items => new {
vertex = items[0],
key = items[1],
value = int.Parse(items[2])
})
.GroupBy(item => item.vertex)
.Select(chunk => new {
vertex = chunk.Key,
dict = chunk.ToDictionary(item => item.key, item => item.value)
});
foreach (var record in records)
g.add_vertex(record.vertex, record.dict);
Does this work for you?
vertices =
File
.ReadLines(#"CSV_testdaten.csv")
.Select(x => x.Split(','))
.Select(x => new { vertex = x[0], name = x[1], value = int.Parse(x[2]) })
.GroupBy(x => x.vertex)
.ToDictionary(x => x.Key, x => x.ToDictionary(y => y.name, y => y.value));
You can split your code in two parts. First will read csv lines:
public static IEnumerable<(string, string, string)> ReadCsvLines()
{
using (var reader = new StreamReader(#"CSV_testdaten.csv"))
{
while (!reader.EndOfStream)
{
string newLine;
while ((newLine = reader.ReadLine()) != null)
{
var values = newLine.Split(',');
yield return (values[0], values[1], values[2]);
}
}
}
}
and second will add those lines to dictionary:
var result = ReadCsvLines()
.ToArray()
.GroupBy(x => x.Item1)
.ToDictionary(x => x.Key, x => x.ToDictionary(t => t.Item2, t => int.Parse(t.Item3)));
With your input result would be:

split string to Dictionnary<string, int>

I have a string like that : "content;123 contents;456 contentss;789 " etc..
I would like to split this string to get a Dictionary, but I don't know you to make it. I try to split the string but I got a List only.
The content (before semi colon) is always a unique string.
After the semi colon, I always have a number until I found the space.
the number is always an int (no float needs).
Could someone help me please ?
You can use the following LINQ expression:
"content;123 contents;456 contentss;789"
.Split(' ')
.Select(x => x.Split(';'))
.ToDictionary(x => x[0], x => int.Parse(x[1]));
string input = "content1;123 content2;456 content3;789";
var dict = Regex.Matches(input, #"(.+?);(\d+)").Cast<Match>()
.ToDictionary(m => m.Groups[1].Value, m => int.Parse(m.Groups[2].Value));
You can do something like this:
string value = "content;123 contents;456 contentss;789";
Dictionary<string, int> data = new Dictionary<string,int>();
foreach(string line in value.Split(' '))
{
string[] values = line.Split(';');
if (!data.ContainsKey(values[0]))
{
data.Add(values[0], Convert.ToInt32(values[1]));
}
}
var myList = "content1;number1 content2;number2 content3;number3";
var myDictionary = myList.Split(' ').Select(pair => pair.Split(';')).ToDictionary(splitPair => splitPair[0], splitPair => int.Parse(splitPair[1]));
static void Main(string[] args)
{
string content = "content;123 contents;456 contentss;789";
Dictionary<string, int> result = new Dictionary<string, int>();
content.Split(' ').ToList().ForEach(x =>
{
var items = x.Split(';');
result.Add(items[0], int.Parse(items[1]));
});
foreach(var item in result)
{
Console.WriteLine("{0} -> {1}" , item.Key, item.Value);
}
}

Find most common element in array

I have a string array that can contains 1 or more elements with various string values. I need to find the most common string in the array.
string aPOS[] = new string[]{"11","11","18","18","11","11"};
I need to return "11" in this case.
Try something like this using LINQ.
int mode = aPOS.GroupBy(v => v)
.OrderByDescending(g => g.Count())
.First()
.Key;
If you don't like using LINQ or are using e.g. .Net 2.0 which does not have LINQ, you can use foreach loops
string[] aPOS = new string[] { "11", "11", "18", "18", "11", "11"};
var count = new Dictionary<string, int>();
foreach (string value in aPOS)
{
if (count.ContainsKey(value))
{
count[value]++;
}
else
{
count.Add(value, 1);
}
}
string mostCommonString = String.Empty;
int highestCount = 0;
foreach (KeyValuePair<string, int> pair in count)
{
if (pair.Value > highestCount)
{
mostCommonString = pair.Key;
highestCount = pair.Value;
}
}
You can do this with LINQ, the following is untested, but it should put you on the right track
var results = aPOS.GroupBy(v=>v) // group the array by value
.Select(g => new { // for each group select the value (key) and the number of items into an anonymous object
Key = g.Key,
Count = g.Count()
})
.OrderByDescending(o=>o.Count); // order the results by count
// results contains the enumerable [{Key = "11", Count = 4}, {Key="18", Count=2}]
Here's the official Group By documentation

C# : Merging Dictionary and List

I have a List of String like
List<String> MyList=new List<String>{"A","B"};
and a
Dictionary<String, Dictionary<String,String>> MyDict=new Dictionary<String,Dictionary<String,String>>();
which contains
Key Value
Key Value
"ONE" "A_1" "1"
"A_2" "2"
"X_1" "3"
"X_2" "4"
"B_1" "5"
"TWO" "Y_1" "1"
"B_9" "2"
"A_4" "3"
"B_2" "6"
"X_3" "7"
I need to merge the the list and Dictionary into a new Dictionary
Dictionary<String,String> ResultDict = new Dictionary<String,String>()
The resulting dictionary contains
Key Value
"A_1" "1"
"A_2" "2"
"B_1" "5"
"A_4" "3"
"B_2" "6"
"X_2" "4"
"X_3" "7"
Merge rule
First add the items which has a substring equals to any item in the list.
Then Merge the items in the "MyDict" so the result should not contain duplicate keys as well as duplicate values.
Here is my source code.
Dictionary<String, String> ResultDict = new Dictionary<string, string>();
List<String> TempList = new List<string>(MyDict.Keys);
for (int i = 0; i < TempList.Count; i++)
{
ResultDict = ResultDict.Concat(MyDict[TempList[i]])
.Where(TEMP => MyList.Contains(TEMP.Key.Contains('_') == true ? TEMP.Key.Substring(0, TEMP.Key.LastIndexOf('_'))
: TEMP.Key.Trim()))
.ToLookup(TEMP => TEMP.Key, TEMP => TEMP.Value)
.ToDictionary(TEMP => TEMP.Key, TEMP => TEMP.First())
.GroupBy(pair => pair.Value)
.Select(group => group.First())
.ToDictionary(pair => pair.Key, pair => pair.Value); }
for (int i = 0; i < TempList.Count; i++)
{
ResultDict = ResultDict.Concat(MyDict[TempList[i]])
.ToLookup(TEMP => TEMP.Key, TEMP => TEMP.Value)
.ToDictionary(TEMP => TEMP.Key, TEMP => TEMP.First())
.GroupBy(pair => pair.Value)
.Select(group => group.First())
.ToDictionary(pair => pair.Key, pair => pair.Value);
}
its working fine, but I need to eliminate the two for loops or at least one
(Any way to do this using LINQ or LAMBDA expression)
Here's one way you could do it with LINQ and lambdas, as requested:
var keysFromList = new HashSet<string>(MyList);
var results =
MyDict.Values
.SelectMany(x => x)
.OrderBy(x => {
int i = x.Key.LastIndexOf('_');
string k = (i < 0) ? x.Key.Trim()
: x.Key.Substring(0, i);
return keysFromList.Contains(k) ? 0 : 1;
})
.Aggregate(new {
Results = new Dictionary<string, string>(),
Values = new HashSet<string>()
},
(a, x) => {
if (!a.Results.ContainsKey(x.Key)
&& !a.Values.Contains(x.Value))
{
a.Results.Add(x.Key, x.Value);
a.Values.Add(x.Value);
}
return a;
},
a => a.Results);
Loop wise this code is simpler, but not Linq:
public static Dictionary<string, string> Test()
{
int initcount = _myDict.Sum(keyValuePair => keyValuePair.Value.Count);
var usedValues = new Dictionary<string, string>(initcount); //reverse val/key
var result = new Dictionary<string, string>(initcount);
foreach (KeyValuePair<string, Dictionary<string, string>> internalDicts in _myDict)
{
foreach (KeyValuePair<string, string> valuePair in internalDicts.Value)
{
bool add = false;
if (KeyInList(_myList, valuePair.Key))
{
string removeKey;
if (usedValues.TryGetValue(valuePair.Value, out removeKey))
{
if (KeyInList(_myList, removeKey)) continue;
result.Remove(removeKey);
}
usedValues.Remove(valuePair.Value);
add = true;
}
if (!add && usedValues.ContainsKey(valuePair.Value)) continue;
result[valuePair.Key] = valuePair.Value;
usedValues[valuePair.Value] = valuePair.Key;
}
}
return result;
}
private static bool KeyInList(List<string> myList, string subKey)
{
string key = subKey.Substring(0, subKey.LastIndexOf('_'));
return myList.Contains(key);
}

Categories