I have another problem converting an array from php to c#.
public $array = array(103 => array('', ''), 102 => array('', ''), 101 => array('', '', ''), 100 => array('', '', '', ''));
This is what I have:
public Dictionary<int, List<string>> waddlesById = new Dictionary<int, List<string>>();
problem is whenever I do this:
sizeof($this->array[$waddleId]) - 1
That equals -1, but when do it in c#:
waddlesById[waddleId].Count - 1
equals 0.
This is my construct function:
string maxSeats = String.Empty;
foreach (int waddleId in sledRacing)
{
switch (waddleId)
{
case 103:
case 102:
maxSeats = ",";
break;
case 101:
maxSeats = ",,";
break;
case 100:
maxSeats = ",,,";
break;
}
if (waddlesById.ContainsKey(waddleId))
{
waddlesById[waddleId].Add(maxSeats);
}
else
{
List<string> newInner = new List<string>();
newInner.Add(maxSeats);
waddlesById.Add(waddleId, newInner);
}
}
Any help is appreciated
Using .Count will automatically create the entry. Use waddlesById.ContainsKey(waddleId) instead: http://msdn.microsoft.com/en-us/library/htszx2dy.aspx
I think you are confusing Lists and Arrays in C#. #Simon Witehead is right, you probably need to rethink your code in C# idioms. At the same time it reminded me the LookUp type (which I believe not that commonly known) and I though I'd try to answer you question in (hopefully) somewhat useful way.
Before that, let me clear one thing first: I assume you are trying to create an array with this code:
maxSeats = ",,,";
If that's correct, then here is how you create an array with three elements:
var myArray = new string[3];
// or similar to your PHP code
var myArray = new string[] { "", "", "" };
As for the LookUp example, I think, it provides a more C# idiomatic way of doing this kind of task:
var sledRacing = new[] { 100, 102, 103, 100, 100, 102, 101 };
var lu = sledRacing.ToLookup(
k => k,
k => k == 100 ? new string[3] : (k == 101 ? new string[2] : new string[1])
);
foreach (var g in lu)
{
Console.WriteLine(g.Key);
foreach (var i in g)
{
Console.WriteLine(" - " + i.Length);
}
}
This will produce the following output:
100
- 3
- 3
- 3
102
- 1
- 1
103
- 1
101
- 2
Having said all that (and not knowing much about PHP, so I can't tell if the language lack dynamically sized array or lists and compare), you might need to rethink your code: If you want to use a List then you don't need to size it to start with. Then you might want to be more 'Object oriented' and encapsulate 'Racing Waddle' in a class and use the dictionary (or LookUp) to index them by their id and so on.
There is a similar example on MSDN using LookUp type, that might help too.
Related
I want to rank the number i added up from first to third but i cant think of a way to rank it properly since when there is a duplicate it will only show the number once and continues to the second highest
im new to the language and it would be great for someone to help me on this
Edit: Sorry i think there is a misunderstanding here my sums are in an array that is connected to the names in another array and im trying to sort it out with the same index value
Edit 2: Also i am stuck at c# 7.3 so i cant use some of the new codes
int first = Int32.MinValue;
int fs, nd, thr;
int temp = 0;
for (fs = 0; fs < hounds; fs++)
{
if (score_SUM[fs] > first)
{
first = score_SUM[fs];
temp = fs;
}
}
Console.WriteLine("\n" + "First:{1} {0}", first, houndname[temp]);
int second = Int32.MinValue;
for (nd = 0; nd < hounds; nd++)
{
if (score_SUM[nd] > second && score_SUM[nd] < first)
{
second = score_SUM[nd];
temp = nd;
}
}
Console.WriteLine("Second:{1} {0}", second, houndname[temp]);
int third = Int32.MinValue;
for (thr = 0; thr < hounds; thr++)
{
if (score_SUM[thr] > third && score_SUM[thr] < second)
{
third = score_SUM[thr];
temp = thr;
}
}
Console.WriteLine("Third:{1} {0}", third, houndname[temp]);
Console.ReadLine();
example
10 , 5 , 10 , 6, 1
The output will be like
10
6
5
But I expected
10
10
6
but i cant find a way to write a block a code for that
You're drastically over-engineering this.
If what you have is an array (or list/collection of some kind) of values then you can simply sort that array (descending in this case) and display the first three values.
For example, consider this list of values:
var hounds = new List<int> { 10, 5, 10, 6, 1 };
Then you can sort that list:
hounds = hounds.OrderByDescending(h => h).ToList();
And, either in a loop or by directly referencing the first three (if you know there will always be at least three), output them. For example:
Console.WriteLine("First:{0}", hounds[0]);
Console.WriteLine("Second:{0}", hounds[1]);
Console.WriteLine("Third:{0}", hounds[2]);
Regarding your edit...
my sums are in an array that is connected to the names in another array and im trying to sort it out with the same index value
You're doing it wrong.
Instead of trying to manually keep multiple arrays of values synchronized, maintain one array of meaningful objects. For example, consider how you define a "hound":
public class Hound
{
public int Value { get; set; }
public string Name { get; set; }
}
Create your list of hounds, not multiple lists of disconnected and unrelated values that you need to manually remember and keep synchronized. For example:
var hounds = new List<Hound>
{
new Hound { Value = 10, Name = "Fido" },
new Hound { Value = 5, Name = "Barney" },
new Hound { Value = 10, Name = "Jake" },
new Hound { Value = 6, Name = "Woof" },
new Hound { Value = 1, Name = "Dog" }
};
The rest of the process is the same. Sort the list:
hounds = hounds.OrderByDescending(h => h.Value);
And output the data:
Console.WriteLine("First:{1} {0}", hounds[0].Value, hounds[0].Name);
Console.WriteLine("Second:{1} {0}", hounds[1].Value, hounds[1].Name);
Console.WriteLine("Third:{1} {0}", hounds[2].Value, hounds[2].Name);
Overall, the main point here is that you don't need a ton of convoluted logic just to get the top 3 values in a list. Sorting is a common and well-established operation. All you need is the right data structure to be sorted.
Or, as usual, someone else has already said it better before...
"Smart data structures and dumb code works a lot better than the other way around."
Eric S. Raymond, The Cathedral & the Bazaar
Does this answer your question?
List<int> list = new() { 10, 5, 10, 6, 1 };
list.Sort((x, y) => y.CompareTo(x));
for (int i = 0; i < 3; i++)
{
Console.WriteLine(list[i]);
}
If you only want the three highest values you can also do this:
List<int> list = new() { 10, 5, 10, 6, 1 };
IEnumerable<int> highestValues = list.OrderByDescending(x => x).Take(3);
foreach (int value in highestValues)
{
Console.WriteLine(value);
}
Just change your < symbols to <= symbols. So your checks for the second and third ranks would look something like this:
// check for second
if (score_SUM[nd] > second && score_SUM[nd] <= first)
...
// check for third
if (score_SUM[thr] > third && score_SUM[thr] <= second)
...
I have a problem with code.
I want to implement radix sort to numbers on c# by using ling.
I give as input string and give 0 in the start of the number:
foreach(string number in numbers){<br>
if(number.lenth > max_lenth) max_lenth = number.lenth;<br><br>
for(int i = 0; i < numbers.lenth; i++){<br>
while(numbers[i].length < max_lenth) numbers[i] = "0" + numbers[i];<br><br>
after this I need to order by each number in string, but it doesn't work with my loop:
var output = input.OrderBy(x => x[0]);
for (int i = 0; i < max_lenth; i++)
{
output = output.ThenBy(x => x[i]);
}
so I think to create a string that contain "input.OrderBy(x => x[0]);" and add "ThenBy(x => x[i]);"
while max_length - 1 and activate this string that will my result.
How can I implement it?
I can't use ling as a tag because its my first post
If I am understanding your question, you are looking for a solution to the problem you are trying to solve using Linq (by the way, the last letter is a Q, not a G - which is likely why you could not add the tag).
The rest of your question isn't quite clear to me. I've listed possible solutions based on various assumptions:
I am assuming your array is of type string[]. Example:
string[] values = new [] { "708", "4012" };
To sort by alpha-numeric order regardless of numeric value order:
var result = values.OrderBy(value => value);
To sort by numeric value, you can simply change the delegate used in the OrderBy clause assuming your values are small enough:
var result = values.OrderBy(value => Convert.ToInt32(value));
Let us assume though that your numbers are arbitrarily long, and you only want the values in the array as they are (without prepending zeros), and that you want them sorted in integer value order:
string[] values = new [] { "708", "4012" };
int maxLength = values.Max(value => value.Length);
string zerosPad = string
.Join(string.Empty, Enumerable.Repeat<string>("0", maxLength));
var resultEnumerable = values
.Select(value => new
{
ArrayValue = value,
SortValue = zerosPad.Substring(0, maxLength - value.Length) + value
}
)
.OrderBy(item => item.SortValue);
foreach(var result in resultEnumerable)
{
System.Console.WriteLine("{0}\t{1}", result.SortValue, result.ArrayValue);
}
The result of the above code would look like this:
0708 708
4012 4012
Hope this helps!
Try Array.Sort(x) or Array.Sort(x,StringComparer.InvariantCulture).
I'm using the following code:
public class Card
{
public Card(Rank rank, Suit suit)
{
this.Rank = rank;
this.Suit = suit;
}
public Rank Rank { get; private set; }
public Suit Suit { get; private set; }
}
public enum Rank : byte
{
Ace = 1,
Two = 2,
Three = 3,
Four = 4,
Five = 5,
Six = 6,
Seven = 7,
Eight = 8,
Nine = 9,
Ten = 10,
Jack = 11,
Queen = 12,
King = 13,
}
public enum Suit : byte
{
Club = 1, // Klavers
Diamond = 2, // Ruiten
Heart = 3, // Harten
Spades = 4 // Schoppen
}
public class Deck
{
private List<Card> deck = new List<Card>(52);
public Deck()
{
this.FillStack();
}
public void FillStack()
{
this.deck.Clear();
this.deck.AddRange(
Enumerable.Range(1,4)
.SelectMany( s =>
Enumerable.Range(1, 13)
.Select( n => new Card( (Rank)n , (Suit)s ) )
)
) ;
}
Can I replace the LINQ-based code in FillStack with equivalent code based on a for loop? The goal is to make the code easier to understand and extend for those who are less familiar with LINQ.
Yes, this looks like a good example of how not to use the LINQ helper methods. There is no advantage over a plain old and far more readable
for (int s = 1; s <= 4; s++)
for (int n = 1; n <= 13; n++)
this.deck.Add(new Card((Rank)n, (Suit)s));
The LINQ version could be made somewhat more readable though: here's how it could look when not attempting to stuff it all into a single expression.
var suits = Enumerable.Range(1, 4);
var ranks = Enumerable.Range(1, 13);
var cards =
from s in suits
from n in ranks
select new Card((Rank)n, (Suit)s);
this.deck.AddRange(cards);
This should be easier to understand, but it still means pretty much the same thing.
You could just say something like this
public void FillStack()
{
this.deck.Clear() ;
this.deck.AddRange(
Enumerable
.Range(0,52)
.Select( n => new Card( (Rank)(1+n%13), (Suit)(1+n/13) ) )
) ;
return ;
}
Or even
public void FillStack()
{
this.deck.Clear() ;
foreach ( Rank rank in Enum.GetValues(typeof(Rank)) )
{
foreach( Suit suit in Enum.GetValues(typeof(Suit)) )
{
Card card = new Card( rank , suit ) ;
this.deck.Add( card ) ;
}
}
return;
}
Your question is to replace the LINQ query with for loop so it's easier to understand. That's fair enough. But since you are learning it's worth to understand the query itself. Then you will be able to replace it yourself or, better yet, you will be comfortable enough with it to leave it there.
Let's break it down and try to explain it line by line:
[1] this.deck
[2] .AddRange(
[3] Enumerable.Range(1, 4)
[4] .SelectMany(s =>
[5] Enumerable.Range(1, 13)
[6] .Select(n =>
[7] new Card((Rank)n, (Suit)s))));
Start from the line #3 Enumerable.Range(1,4) - the method returns range of numbers from 1 to 4. So we have a collection 1, 2, 3, 4. In line #4 we access this collection item by item. So we actually iterate over the items. Each item is denoted by a variable s - you can use it to access the items. The same mechanism is repeated to create iteration from 1 to 13 (lines #5 and #6). The items in the second iteration are accessed by variable n.
Bigger picture - we iterate from 1 to 4 and inside that we iterate from 1 to 13. Now, in line #7 we create a Card and the numbers from both iterations - denoted as n and s - are used in the constructor of the class. Because we iterate through number from 1 to 4 and inside that from 1 to 13 we will get all the combinations: (1,1) (1,2) (1,3) (1,4) (2,1) (2,2) and so on. Each item from the combination will create a card. So it will result in a collection of cards. And now go back to line #2 AddRange method is responsible for adding this range of cards to the deck collection.
Hope this will help to understand the query and replace it with more imperative code.
This question already has answers here:
C# find biggest number
(7 answers)
Closed 9 years ago.
I have 3 values stored in the variables v, p, and k. I want to find the greatest among them. The values of the variables are: v = 3, p = 6, and k = 2.
The result should be the name of the variable that contains the maximum value—the text v, p, or k.
How can I do this?
Well, you just obviated every answer already posted by not clearly stating what you wanted the first time. You can extend the use of Enumerable.Max easily to give you what you now want:
string max =
new[] {
Tuple.Create(v, "v"),
Tuple.Create(p, "p"),
Tuple.Create(k, "k")
}.Max()
.Item2;
An alternative is:
string max = v >= p && v >= k ? "v" : p >= v && p >= k ? "p" : "k";
But do you see how much less readable that is than the first version?
The other answers are very good, but for the sake of completeness, I'd like to point out that for simplicity, you can also use Math.Max:
var max = Math.Max(Math.Max(v, p), k);
Update given your updated question, I'd recommend this:
var max = v > p ? v > k ? "V" : p > k ? "P" : "K" : p > k ? "P" : "K";
It's rather unwieldy, but it works (k wins ties with p or v, p wins ties with v).
var values = new List<int> { v, p, k };
var maxValue = values.Max();
Update, re your modified question: The variable names don't exist in the compiled IL code. Therefore you can't easily retrieve them.
But you can create a dictionary. Off the top of my head (I didn't actually try this, but it could be somewhat along these lines):
var dict = new Dictionary<string, int> {
{ "V", 3 }, { "P", 6 }, { "K", 2 }
};
var max = dict.Values.Max();
var relevantKey = dict
.Where(x => max.Equals(x.Value))
.Select(x => x.Key)
.FirstOrDefault()
Here is some hand-maded method, based on generics and Max from Enumerable:
public static T MaxVal<T>(params T[] items)
{
return items == null? default(T) : items.Max();
}
And for integers, for example, you can call it like this:
Console.WriteLine(MaxVal(4, 8, 15, 16, 42));
My following code has compile error,
Error 1 Cannot implicitly convert type 'TestArray1.Foo[,,*]' to 'TestArray1.Foo[][][]' C:\Users\lma\Documents\Visual Studio 2008\Projects\TestArray1\TestArray1\Program.cs 17 30 TestArray1
Does anyone have any ideas? Here is my whole code, I am using VSTS 2008 + Vista 64-bit.
namespace TestArray1
{
class Foo
{
}
class Program
{
static void Main(string[] args)
{
Foo[][][] foos = new Foo[1, 1, 1];
return;
}
}
}
EDIT: version 2. I have another version of code, but still has compile error. Any ideas?
Error 1 Invalid rank specifier: expected ',' or ']' C:\Users\lma\Documents\Visual Studio 2008\Projects\TestArray1\TestArray1\Program.cs 17 41 TestArray1
Error 2 Invalid rank specifier: expected ',' or ']' C:\Users\lma\Documents\Visual Studio 2008\Projects\TestArray1\TestArray1\Program.cs 17 44 TestArray1
namespace TestArray1
{
class Foo
{
}
class Program
{
static void Main(string[] args)
{
Foo[][][] foos = new Foo[1][1][1];
return;
}
}
}
EDIT: version 3. I think I want to have a jagged array. And after learning from the fellow guys. Here is my code fix, and it compile fine in VSTS 2008. What I want is a jagged array, and currently I need to have only one element. Could anyone review whether my code is correct to implement my goal please?
namespace TestArray1
{
class Foo
{
}
class Program
{
static void Main(string[] args)
{
Foo[][][] foos = new Foo[1][][];
foos[0] = new Foo[1][];
foos[0][0] = new Foo[1];
foos[0][0][0] = new Foo();
return;
}
}
}
thanks in advance,
George
Regarding version 2 of your code - unfortunately you can't specify jagged arrays in that way. Instead, you need to do:
Foo[][][] foos = new Foo[1][][];
foos[0] = new Foo[1][];
foos[0][0] = new Foo[1];
You have to populate each array separately, basically. Foo[][][] means "an array of arrays of arrays of Foo." An initialization statement like this is only capable of initializing one array at a time. With the rectangular array, you still end up with just a single (multi-dimensional) array, which is why new Foo[1,1,1] is valid.
If this is for real code by the way, I'd urge you to at least consider other design decisions. Arrays of arrays can be useful, but you can easily run into problems like this. Arrays of arrays of arrays are even nastier. There may be more readable ways of expressing what you're interested in.
Make up your mind :)
You either want:
Foo[,,] foos = new Foo[1, 1, 1];
or:
Foo[][][] foos = new Foo[1][1][1];
You are declaring a double-nested array (array of array of array) and assigning a three-dimensional array. Those two are definitely different. You can change your declaration to
Foo[,,] foos = new Foo[1,1,1]
if you want a truly three-dimensional array. Jagged arrays (the [][][] kind) are not that needed in C# as in, say, Java.
The simplest answer is to use
Foo[,,] foos = new Foo[2, 3, 4];
Which gives you a 3-dimensional array as a contiguous block of memory of 2*3*4=24 Foo's.
The alternative looks like :
Foo[][][] foos = new Foo[2][][];
for (int a = 0; a < foos.Length; a++)
{
foos[a] = new Foo[3][];
for (int b = 0; b < foos[a].Length; b++)
{
foos[a][b] = new Foo [4];
for (int c = 0; c < foos[a][b].Length; c++)
foos[a][b][c] = new Foo();
}
}
Although this jagged (= array of array) approach is a bit more work, using it is actually faster. This is caused by a shortcoming of the compiler that will always do a range check when accessing an element in the Foo[,,] case, while it is able to at least optimize for-loops that use the Length property in the Foo[][][] scenario.
Also see this question
These two different array declarations create very different things.
Let's look at simpler case:
Foo[,] twoDimensionArray = new Foo[5,5];
This array has two dimensions - you can think of it as a table. You need both axis in order to return anything:
Foo item = twoDimensionArray[2,3]
The indexes always have the same lengths - in this case 0-4.
A jagged array is actually an array of arrays:
Foo[][] jaggedArray = new Foo[5][];
jaggedArray[0] = new Foo[2];
jaggedArray[1] = new Foo[4];
...
If you only use one axis index it will return an array:
Foo[] oneRow = jaggedArray[3];
If you use both you make your selection from the sub-array:
Foo item = jaggedArray[3][2];
//would be the same as:
Foo item = oneRow[2];
Each of these sub-arrays can have a different length, or even not be populated.
Depends on whether you want them to be jagged or not:
//makes a 5 by 4 by 3 array:
string[,,] foos = new string[5,4,3];
http://msdn.microsoft.com/en-us/library/aa288453(VS.71).aspx
Oh and here is initializing values:
char[, ,] blah = new char[2, 2, 2] {
{{ '1', '2' }, { '3', '4' }},
{{ '5', '6' }, { '7', '8' }}
};
Note that this will not work:
Foo[][][] foos = new Foo[1][1][1];
Because you are using the jagged array syntax, which does not let you define the size of nested arrays. Instead use do this:
Foo[,,] foos = new Foo[1][1][1]; //1 by 1 by 1
or this
Foo[][][] foos = new Foo[1][][]; //1 array allowing two nested levels of jagged arrays
foos[0] = new Foo[1]; //for the first element, create a new array nested in it
foos[0][0] = new Foo[1]; //create a third level new array nested in it
If it means anything, for just the C# declaration:
int[,,] ary = new int[,,]
{
{ { 111, 112 }, { 121, 122 }, { 131, 132 } }
, { { 211, 212 }, { 221, 222 }, { 231, 232 } }
, { { 311, 312 }, { 321, 322 }, { 331, 332 } }
, { { 411, 412 }, { 421, 422 }, { 431, 432 } }
};
Array Initialization
int[, ,] array3D = new int[,,] { { { 1, 2, 3 }, { 4, 5, 6 } },
{ { 7, 8, 9 }, { 10, 11, 12 } } }
source: Multidimensional Arrays (C# Programming Guide)