Count instances of element in c# list - c#

I'd like to know how to Count the instances of the first element in a list, then the second etc. and output these values.
var SPFK_List = new List<string>() {
"one", "one", "one",
"two", "two",
"three", "three", "three"
};
Inputs.ones.Value = *(number of one's)*
Inputs.twos.Value = *(number of two's)*

Try GroupBy (Linq), e.g.:
using System.Linq;
...
var SPFK_List = new List<string>() {
"one", "one", "one",
"two", "two",
"three", "three", "three"
};
// {3, 2, 3}
int[] counts = SPFK_List
.GroupBy(item => item)
.Select(group => group.Count())
.ToArray();
Or (add Where if you want to count only some items)
// {{"one", 3}, {"two", 2}, {"three", 3}}
Dictionary<string, int> counts = SPFK_List
//.Where(item => item == "one" || item == "two")
.GroupBy(item => item)
.ToDictionary(group => group.Key, group => group.Count());
Inputs.ones.Value = counts.TryGetValue("one", out int count) ? count : 0;

A possible solution:
Inputs.ones.Value = SPFK_List.Where(x => x.Equals("one")).Count();

Simply use Count method from System.Linq with overload accepting a Func<TSource,bool> predicate
var SPFK_List = new List<string>() {
"one", "one", "one",
"two", "two",
"three", "three", "three"
};
Inputs.ones.Value = SPFK_List.Count(s => s.Equals("one", StringComparison.Ordinal));
Inputs.twos.Value = SPFK_List.Count(s => s.Equals("two", StringComparison.Ordinal));

Related

How do I sort numbers written in string format("one "two" three" etc.) according to their value using LINQ C# lambda expressions

public static IEnumerable<string> OrderingReversal()
{
string[] digits = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" };
var res = digits.Where(w => w[1] == 'i')
.OrderByDescending(w => Convert.ToInt32(w)).ToList<string>();
return res;
}
I would like the output to be: "nine", "eight", "six" and "five"
I tried to achieve this by the code I provided above.
However, I am receiving runtime error:
System.FormatException: 'Input string was not in a correct format.'
Any Help would be appreciated.
Thank you!
A big part of the solution is found in other answers like this one but more is needed to sort the results.
Here's a class that will take a list of strings and return them sorted by the numeric values they represent:
public delegate long ConvertStringToNumberDelegate(string number);
public class NumbersAsTextSorter
{
private readonly ConvertStringToNumberDelegate _convertStringToNumberFunction;
public NumbersAsTextSorter(ConvertStringToNumberDelegate convertStringToNumberFunction)
{
_convertStringToNumberFunction = convertStringToNumberFunction;
}
public IEnumerable<string> ReverseSort(IEnumerable<string> input)
{
var textWithNumbers = input.Select(i => new {input = i, value = _convertStringToNumberFunction(i)});
return textWithNumbers.OrderByDescending(t => t.value).Select(s => s.input);
}
}
This will create a collection of text inputs matched with numeric values. It sorts the collection by the numeric value and then returns the text inputs in that sorted order.
As you can see, a critical detail is missing. How do you convert "one" to 1, "two" to 2, and so forth?
For that you need an implementation of the delegate - ConvertStringToNumberDelegate. You can get that by using the class in the the answer I referenced above.
For convenience I've copied that static method (for which I am explicitly not taking credit!) into a static class:
public static class TestToNumbers
{
private static Dictionary<string, long> numberTable =
new Dictionary<string, long>
{{"zero",0},{"one",1},{"two",2},{"three",3},{"four",4},
{"five",5},{"six",6},{"seven",7},{"eight",8},{"nine",9},
{"ten",10},{"eleven",11},{"twelve",12},{"thirteen",13},
{"fourteen",14},{"fifteen",15},{"sixteen",16},
{"seventeen",17},{"eighteen",18},{"nineteen",19},{"twenty",20},
{"thirty",30},{"forty",40},{"fifty",50},{"sixty",60},
{"seventy",70},{"eighty",80},{"ninety",90},{"hundred",100},
{"thousand",1000},{"million",1000000},{"billion",1000000000},
{"trillion",1000000000000},{"quadrillion",1000000000000000},
{"quintillion",1000000000000000000}};
public static long ToLong(string numberString)
{
var numbers = Regex.Matches(numberString, #"\w+").Cast<Match>()
.Select(m => m.Value.ToLowerInvariant())
.Where(v => numberTable.ContainsKey(v))
.Select(v => numberTable[v]);
long acc = 0, total = 0L;
foreach (var n in numbers)
{
if (n >= 1000)
{
total += (acc * n);
acc = 0;
}
else if (n >= 100)
{
acc *= n;
}
else acc += n;
}
return (total + acc) * (numberString.StartsWith("minus",
StringComparison.InvariantCultureIgnoreCase) ? -1 : 1);
}
}
Now you can create an instance of NumbersAsTextSorter which uses that static method to convert text to numbers. I've done that in this unit test which passes:
[TestMethod]
public void TestSorting()
{
var sorter = new NumbersAsTextSorter(TestToNumbers.ToLong);
var output = sorter.ReverseSort(new string[] { "one", "three hundred", "zero" });
Assert.IsTrue(output.SequenceEqual(new string[] { "three hundred", "one", "zero" }));
}
For clarity, this is passing in "one", "three hundred", and "zero" and asserting that after it's sorted, the sequence is "three hundred", "one", "zero".
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
string[] digits = { "Zero", "one", "two", "Three", "four", "five", "Six", "seven", "eight", "nine" };
var asc = OrderNumberStringsByValue(digits);
var dec = OrderNumberStringsByValue(digits, true);
string[] myDigits = { "Eight", "nine", "Five", "six" };
var myAsc = OrderNumberStringsByValue(myDigits);
var myDec = OrderNumberStringsByValue(myDigits, true);
Console.WriteLine($"asc: {string.Join(", ", asc)}");
Console.WriteLine($"dec: {string.Join(", ", dec)}");
Console.WriteLine($"myAsc: {string.Join(", ", myAsc)}");
Console.WriteLine($"myDec: {string.Join(", ", myDec)}");
Console.ReadLine();
}
public static IEnumerable<string> OrderNumberStringsByValue(IEnumerable<string> numbers, bool decending = false)
{
return numbers.OrderBy(n => (decending ? -1 : 1) * (int)Enum.Parse(typeof(Numbers), n.ToLower()));
}
}
enum Numbers : int
{
zero = 0,
one = 1,
two = 2,
three = 3,
four = 4,
five = 5,
six = 6,
seven = 7,
eight = 8,
nine = 9
}
}

C#: Loop or Array

i have this code for c#
var wordCounts1 = myInterface.GetWordCounts(new[] {
"one", "one", "two", "three", "three",});
the expected output should be:
{"one", 2}, {"two", 1}, {"three",2}
what should I use to get this output loop or array?
Grouping by word should work
new[] { "one", "one", "two", "three", "three" }
.GroupBy(x => x)
.Select(x => new
{
Word = x.Key,
Count = x.Count()
});

Adding array to Jagged Array c#

I've had a look at both ASP.Net c# adding items to jagged array and vb.net assign array to jagged array but I just can't seem to work this out...
So, essentially, it's this. I have a function that builds a list of values from a query or two. I'm adding each value returned to a list then converting the list to an array. All is good
However, I now need to return two values, so a multi dimension array appears more suitable. Essentially, this is what I want to do:
string[][] array2D = new string[2][];
array2D[0] = new string[3] { "one", "two", "three" };
array2D[1] = new string[3] { "abc", "def", "ghi" };
All good so far. However, I don't know the values that I want to plug in to the array at the time of array initialisation, so, this is what I'd expect to be able to do:
string[][] array2D = new string[2][];
//array2D[0] = new string[3] { "one", "two", "three" };
//array2D[1] = new string[3] { "abc", "def", "ghi" };
string[] deviceIDS = { "one", "two", "three" };
string[] groupIDS = { "abc", "def", "ghi" };
array2D[0] = new string[deviceIDS.Length] deviceIDS;
array2D[1] = new string[deviceIDS.Length] groupIDS;
But it really doesn't like the last two lines, report it needs a ;
You have already created arrays here:
string[] deviceIDS = { "one", "two", "three" };
string[] groupIDS = { "abc", "def", "ghi" };
So you only need to set references to these arrays:
array2D[0] = deviceIDS;
array2D[1] = groupIDS;

LINQ Select from two Collections with same length

var listA = new List<string> {"One", "Two", "Three"};
var listB = new List<int> {1, 2, 3};
var listC = new List<Tuple<string, int>>();
Here I've got two Lists with the same length. Is there a way to fill third listC with LINQ?
"One", 1
"Two", 2
"Three", 3
I think you are looking the Zip extension method:
var listA = new List<string> { "One", "Two", "Three" };
var listB = new List<int> { 1, 2, 3 };
var listC = listA.Zip(listB, (s, i) => new Tuple<string, int>(s, i)).ToList();

How can I initialize a C# List in the same line I declare it. (IEnumerable string Collection Example)

I am writing my testcode and I do not want wo write:
List<string> nameslist = new List<string>();
nameslist.Add("one");
nameslist.Add("two");
nameslist.Add("three");
I would love to write
List<string> nameslist = new List<string>({"one", "two", "three"});
However {"one", "two", "three"} is not an "IEnumerable string Collection". How can I initialise this in one line using the IEnumerable string Collection"?
var list = new List<string> { "One", "Two", "Three" };
Essentially the syntax is:
new List<Type> { Instance1, Instance2, Instance3 };
Which is translated by the compiler as
List<string> list = new List<string>();
list.Add("One");
list.Add("Two");
list.Add("Three");
Change the code to
List<string> nameslist = new List<string> {"one", "two", "three"};
or
List<string> nameslist = new List<string>(new[] {"one", "two", "three"});
Just lose the parenthesis:
var nameslist = new List<string> { "one", "two", "three" };
Posting this answer for folks wanting to initialize list with POCOs and also coz this is the first thing that pops up in search but all answers only for list of type string.
You can do this two ways one is directly setting the property by setter assignment or much cleaner by creating a constructor that takes in params and sets the properties.
class MObject {
public int Code { get; set; }
public string Org { get; set; }
}
List<MObject> theList = new List<MObject> { new MObject{ PASCode = 111, Org="Oracle" }, new MObject{ PASCode = 444, Org="MS"} };
OR by parameterized constructor
class MObject {
public MObject(int code, string org)
{
Code = code;
Org = org;
}
public int Code { get; set; }
public string Org { get; set; }
}
List<MObject> theList = new List<MObject> {new MObject( 111, "Oracle" ), new MObject(222,"SAP")};
This is one way.
List<int> list = new List<int>{ 1, 2, 3, 4, 5 };
This is another way.
List<int> list2 = new List<int>();
list2.Add(1);
list2.Add(2);
Same goes with strings.
Eg:
List<string> list3 = new List<string> { "Hello", "World" };
List<string> nameslist = new List<string> {"one", "two", "three"} ?
Remove the parentheses:
List<string> nameslist = new List<string> {"one", "two", "three"};
It depends which version of C# you're using, from version 3.0 onwards you can use...
List<string> nameslist = new List<string> { "one", "two", "three" };
I think this will work for int, long and string values.
List<int> list = new List<int>(new int[]{ 2, 3, 7 });
var animals = new List<string>() { "bird", "dog" };

Categories

Resources