Counting values matched in an array - c#

Ok so, I am looking through a document for certain values, and if they match the values in this array, then I want to increase the count for that specific value. I did this:
public static class Hex
{
//example only, not real code
public static string[] name = {"aba", "bcd", "c"};
public static int[] count = new int[name.Length];
}
But it seems like there must be a better/easier way. Maybe an array of tuple? I just don't know. I know its a pretty easy question, I just can't think of quite how to do it with both strings to compare in 1, and int count for them. Thanks!

use Dictionary<TKey, TValue> Class
Dictionary<string, int> dictionary = new Dictionary<string, int>();
dictionary.Add("aba", 0);
dictionary.Add("bcd", 0);
dictionary.Add("c", 0);
Later you can search for the word in Dictionary.Keys and increment the counter.

What about a Dictionary<string, int>?

I would use a Dictionary<string, int> since it is very efficient:
public static class Hex
{
static Hex()
{
_HexNameCounts = new Dictionary<string, int>()
{
{"aba", 0}, {"bcd", 0}, {"c", 0}
};
}
private static Dictionary<string, int> _HexNameCounts = null;
public static int? GetHexNameCount(string name)
{
int count;
if (_HexNameCounts.TryGetValue(name, out count))
return count;
return null;
}
public static void SetHexNameCount(string name, int count)
{
_HexNameCounts[name] = count;
}
public static void IncreaseHexNameCount(string name, int count = 1)
{
int c = GetHexNameCount(name) ?? 0;
SetHexNameCount(name, c + count);
}
}
Now you can use it in this way:
int? abaCount = Hex.GetHexNameCount("aba");
// or
Hex.SetHexNameCount("c", 3);
// or
Hex.IncreaseHexNameCount("foo", 10);
It's always good to encapsulate complexity in methods. That makes the code more readable and safer.
I have used a Nullable<int> to handle the case that the name is new.

Use a Dictionary:
Dictionary<string, int> matches = new Dictionary<string, int>();
foreach(var item in document)
{
if(matches.ContainsKey(item.stringvalue))
{
matches[item.stringvalue] += 1;
}
else
{
matches.Add(item.stringvalue, 1);
}
}

You can use a dictionary as bellow:
Dictionary<string, int> dicObj = new Dictionary<string, int>();
dicObj.Add("abc", 0);
…
After that you can search for the particular word in this using dicObj.ContainsKey and you can perform your business logic.

Related

Get key in dictionary with optional tuple parameter

I have a dictionary that looks like this Dictionary<Tuple<int, int, bool>, string>
Let's say I have an entry like (1, 2, true) = "Word"
I want to be able to index the dictionary by only doing (1, null, true) and I want it to return the entry I mentioned before since the first and third values in the tuple are the same (ignoring the second since it's null)
Is there a way to do this? If not what is a suggestion for a new structure that would accomplish this? Thanks
I'd suggest you to create a struct to use instead of your Tuple, overriding GethashCode() (implement Equals too, to be consistent) :
public struct MyStruct
{
public int? FirstNumber { get; set; }
public int? SecondNumber { get; set; }
public bool TheBoolean { get; set; }
public override bool Equals(object obj)
{
return this.Equals((MyStruct)obj);
}
public bool Equals(MyStruct obj)
{
return (!obj.FirstNumber.HasValue || !this.FirstNumber.HasValue ||
obj.FirstNumber.Value == this.FirstNumber.Value)
&& (!obj.SecondNumber.HasValue || !this.SecondNumber.HasValue ||
obj.SecondNumber.Value == this.SecondNumber.Value)
&& obj.TheBoolean == this.TheBoolean;
}
public override int GetHashCode()
{
return (!this.FirstNumber.HasValue ? 0 : this.FirstNumber.GetHashCode())
^ (!this.SecondNumber.HasValue ? 0 : this.SecondNumber.GetHashCode())
^ this.TheBoolean.GetHashCode();
}
}
public static void Test()
{
var obj1 = new MyStruct
{
FirstNumber = 1,
SecondNumber = 2,
TheBoolean = true
};
var obj2 = new MyStruct
{
FirstNumber = 1,
SecondNumber = null,
TheBoolean = true
};
var dico = new Dictionary<MyStruct, string>
{
{ obj1, "Word" }
};
var result = dico[obj2];
Console.WriteLine(result);
}
The idea behind a Dictionary<TKey, TValue> is that you really need to have identical match between your TKey, TValuepairs. So, according to your structure, you could try something like this:
Dictionary<tuple<int, bool>, string>
where, in the dictionary creation step, you take in two ints, and combine them into a new, unitque value to add to your dictionary. Here is an example:
public static void AddToDictionary(
this Dictionary<Tuple<int, bool>, string> dictionary,
Tuple<int, int, bool> oldKey,
string value)
{
var key = new Tuple<int, bool>(oldKey.Item1 + oldKey.Item2, oldKey.Item3);
dictionary[key] = value;
}
Bear in mind that the key values must be UNIQUE. Otherwise, you will overwrite older entries.
Another structure that you can have is a Dictionary of Dictionaries. Since you are only interested in the first int, and since the second int might be null, you can have this:
Dictionary<int, Dictionary<Tuple<int?, bool>, string>>
This way, you can get something like this:
var keyTuple = new Tuple<int, int?, bool>(1, null, true);
myDictionary[keyTuple .Item1][new Tuple<int?, bool>(keyTuple.Item2, keyTuple.Item3)]
= "string value";
But, again, it starts to get verbose... a lot.

C# evaluate a string expression and return the result

Trying to figure out which approach to use in .net/C# to evaluate a simple expression in runtime. Code must be .net standard compliant, and I dont want weird dependecies.
I have looked into using using Microsoft.CodeAnalysis.CSharp.Scripting:
How can I evaluate C# code dynamically? but it seems overkill for my use case.
public class Evaluate
{
private Dictionary<string, object> _exampleVariables = new Dictionary<string, object>
{
{"x", 45},
{"y", 0},
{"z", true}
};
private string _exampleExpression = "x>y || z";
private string _exampleExpression2 = #"if(x>y || z) return 10;else return 20;
";
public object Calculate(Dictionary<string, object> variables, string expression)
{
var result = //Magical code
return result;
}
}
You can try my Matheval library. It can evaluate string expression in pure C# and support IFELSE, SWITCH statement. I don't use any dependencies.
using System;
using org.matheval;
public class Program
{
public static void Main()
{
Expression expression = new Expression("IF(time>8, (HOUR_SALARY*8) + (HOUR_SALARY*1.25*(time-8)), HOUR_SALARY*time)");
//bind variable
expression.Bind("HOUR_SALARY", 10);
expression.Bind("time", 9);
//eval
Decimal salary = expression.Eval<Decimal>();
Console.WriteLine(salary);
}
}
View my repo at: https://github.com/matheval/expression-evaluator-c-sharp/
In C# you can do this:
class Program
{
private static Func<Dictionary<string, object>, object> function1 = x =>
{
return ((int)x["x"] > (int)x["y"]) || (bool)x["z"];
};
private static Func<Dictionary<string, object>, object> function2 = x =>
{
if (((int)x["x"] > (int)x["y"]) || (bool)x["z"])
{
return 10;
}
else
{
return 20;
}
};
static void Main(string[] args)
{
Dictionary<string, object> exampleVariables = new Dictionary<string, object>
{
{"x", 45},
{"y", 0},
{"z", true}
};
Console.WriteLine(Calculate(exampleVariables, function2));
}
public static object Calculate(Dictionary<string, object> variables, Func<Dictionary<string, object>, object> function)
{
return function(variables);
}
}

Creating a Generic Function to convert an Array into a Dictionary in C#

I have a struct which contains two public variables. I have made an array of that struct, and wish to convert it to a Dictionary.
Here is one such method of accomplishing that:
public class TestClass
{
public struct KeyValuePairs
{
public string variableOne;
public float variableTwo
}
private KeyValuePairs[] keyValuePairs;
private Dictionary<string, float> KeyValuePairsToDictionary()
{
Dictionary<string, float> dictionary = new Dictionary<string, float>();
for(int i = 0; i < keyValuePairs.Length; i++)
{
dictionary.Add(keyValuePairs[i].variableOne, keyValuePairs[i].variableTwo);
}
return dictionary;
}
}
Now, that works for my specific setup, but I wish to try and convert the KeyValuePairsToDictionary() function into a Generic so that it may work across all types.
My first thought, then, was to do something like this:
private Dictionary<T, T> ArrayToDictionary<T>(T[] array)
{
Dictionary<T, T> keyValuePairs = new Dictionary<T, T>();
for(int i = 0; i < array.Length; i++)
{
keyValuePairs.Add(array[i], array[i]); //The problem is right here.
}
return keyValuePairs;
}
As you can probably tell, I can't access the public fields of whatever struct array I am trying to convert into key-value pairs.
With that, how would you suggest I go about performing the generic conversion?
Please note that my specific setup requires that I convert a struct to a dictionary, for I am using the Unity Game Engine.
Thank you.
A generic way of doing this is already implemented in LINQ.
var dict = myArray.ToDictionary(a => a.TheKey);
With your implementation
public struct KeyValuePairs
{
public string variableOne;
public float variableTwo;
}
and an array
KeyValuePairs[] keyValuePairs = ...;
You get
Dictionary<string, KeyValuePairs> dict = keyValuePairs
.ToDictionary(a => a.variableOne);
or alternatively
Dictionary<string, float> dict = keyValuePairs
.ToDictionary(a => a.variableOne, a => a.variableTwo);
Note that the first variant yields a dictionary with values of type KeyValuePairs, while the second one yields values of type float.
According to the conversation, it seems that you are interested on how you would implement this. Here is a suggestion:
public static Dictionary<TKey, TValue> ToDictionary<T, TKey, TValue>(
this IEnumerable<T> source,
Func<T, TKey> getKey,
Func<T, TValue> getValue)
{
var dict = new Dictionary<TKey, TValue>();
foreach (T item in source) {
dict.Add(getKey(item), getValue(item));
}
return dict;
}
Or simply like this, if you want to store the item itself as value
public static Dictionary<TKey, T> ToDictionary<T, TKey>(
this IEnumerable<T> source,
Func<T, TKey> getKey
{
var dict = new Dictionary<TKey, T>();
foreach (T item in source) {
dict.Add(getKey(item), item);
}
return dict;
}
You can use Reflection to achieve that
First of all, add a {get;set;} to the variables to transform them in properties
public struct KeyValuePairs
{
public string variableOne { get; set; }
public float variableTwo { get; set; }
}
Then the method
// T1 -> Type of variableOne
// T2 -> Type of variableTwo
// T3 -> KeyValuesPair type
public static Dictionary<T1, T2> convert<T1,T2,T3>(T3[] data)
{
// Instantiate dictionary to return
Dictionary<T1, T2> dict = new Dictionary<T1, T2>();
// Run through array
for (var i = 0;i < data.Length;i++)
{
// Get 'key' value via Reflection to variableOne
var key = data[i].GetType().GetProperty("variableOne").GetValue(data[i], null);
// Get 'value' value via Reflection to variableTow
var value = data[i].GetType().GetProperty("variableTwo").GetValue(data[i], null);
// Add 'key' and 'value' to dictionary casting to properly type
dict.Add((T1)key, (T2)value);
}
//return dictionary
return dict;
}
I used the following code to test
KeyValuePairs[] val = new KeyValuePairs[5];
val[0] = new KeyValuePairs() { variableOne = "a", variableTwo = 2.4f };
val[1] = new KeyValuePairs() { variableOne = "b", variableTwo = 3.5f };
val[2] = new KeyValuePairs() { variableOne = "c", variableTwo = 4.6f };
val[3] = new KeyValuePairs() { variableOne = "d", variableTwo = 5.7f };
val[4] = new KeyValuePairs() { variableOne = "e", variableTwo = 6.8f };
Dictionary<string, float> dict = convert<string, float,KeyValuePairs>(val);

how to declare a free length 2d array in c#

Good day,
Normally I create 2D array as follow :
string [,] arr = new string [9,4];
This is a 2D array with 9 rows and 4 columns.
I would like to ask, how to create 2D array with any length.
For example, that is not nessecary to set the row to 9, it can be any number, depends on the situation.
what about simple List<List<T>> ?
This is like a concept, you naturally can wrap up this in your custom class, so consumer of your API don't see these wiered nested declarations.
public class Matrix {
private mtx = new List<List<T>>();
public void Append(T value) {
.....
}
public void InsertAt(T value, int row, int column) {
....
}
}
For that you must be using a List<List<string>> instance. Now you can dynamically add anything you want, however this also has the disadvantage over the array format that you need to check for yourself if you have reached the maximum number of rows or columns.
This Matrix class is space (based on access pattern) and performance efficient:
class Matrix<T>
{
readonly Dictionary<int, Dictionary<int, T>> _rows = new Dictionary<int, Dictionary<int, T>>();
public T this[int i, int j]
{
get
{
var row = ExpandOrGet(j);
if (!row.ContainsKey(i)) row[i] = default(T);
UpdateSize(i, j);
return row[i];
}
set
{
ExpandOrGet(j);
_rows[j][i] = value;
UpdateSize(i, j);
}
}
void UpdateSize(int i, int j)
{
if (j > SizeRows) SizeRows = j;
if (i > SizeColums) SizeColums = i;
}
public int SizeRows { get; private set; }
public int SizeColums { get; private set; }
Dictionary<int, T> ExpandOrGet(int j)
{
Dictionary<int, T> result = null;
if (!_rows.ContainsKey(j))
{
result = new Dictionary<int, T>();
_rows[j] = result;
}
else result = _rows[j];
return result;
}
}
Although you can add further utilities to facilitate your workflow.

Creating a multidimensional dictionary in C# for Windows Phone 7.8

I need to store daily statistics in the isolated storage of Windpws Phone which leads me to believe that a multidimensional dictionary would be the most useful but I'm having trouble wrapping my head around the logic needed to get this to work.
The stats looks something like this in pseudocode:
dictionary DailyStats {
1,
[Stats] => dictionary {
[Class] => 5,
[Entertainment] => 3,
[Personnel] => 2,
[Price] => 7,
[Quality] => 6
}
}
I started out with this:
var DailyStats = new Dictionary<int, Dictionary<string, string>>();
But as soon as I wanted to assign values to this structure I got lost quite fast. The values are collected by the app for each day.
I've thought of Linq but it seems to be overkill for what I'm trying to do.
Can anyone point me in the right direction?
Thanks!
If you have one dicionary with StatusClasses???
var DailyStats = new Dictionary<int, StatusClass>();
And:
class StatusClass
{
//substitute the vars for their type
var Class;
var Entertainment;
var Personnel;
var Price;
var Quality;
public StatusClass(var ClassValue, var EntertainmentValue, var Personnel.....)
{
Class = ClassValue;
Entertainment = EntertainmentValue;
...........
}
}
If your keys are fixed Daniel's solution is the way to go. If you want to use a dictionary a static class like this might help:
static class DailyStats
{
static Dictionary<int, Dictionary<string, string>> _dic;
static DailyStats()
{
_dic = new Dictionary<int, Dictionary<string, string>>();
}
public static void Add(int i, string key, string value)
{
if (!_dic.ContainsKey(i))
_dic[i] = new Dictionary<string, string>();
_dic[i][key] = value;
}
public static string Get(int i, string key)
{
if (!_dic.ContainsKey(i) || !_dic[i].ContainsKey(key))
return null;
return _dic[i][key];
}
}
DailyStats.Add(1, "Stats", "a");
Console.WriteLine(DailyStats.Get(1, "Stats"));

Categories