The question is in title.
What does comma mean as a length of array in C#?
How it is called, how to find it on the Internet?
I searched for "how to initialize array in C#" in google but there is no information about this comma.
If I remove comma VS shows an error: "array initializers can only be used in a variable".
Even after assigning it to variable it still shows error.
EntityFramework generates the following code:
migrationBuilder.InsertData(
table: "Test",
columns: new[] { "Name" },
values: new object[,]
{
{ "Test" },
{ "Test1" }
});
The coma does not represent a length, it represent a dimension. In your case, it can be called a 2d array. It allows you to do this:
values: new object[,]
{
{ "Testa", "Testb", "Testc" },
{ "Test1a", "Test1b", "Test1c" }
}
Related
I want this result:
[[1,2],[1,3],[1,4,5,6],[1,4,5,7]]
from the following set of objects:
var andsOrs =
Ands(items: [
single(1),
Ors(items: [
single(2),
single(3),
Ands(items: [
single(4),
single(5),
Ors(items: [
single(6),
single(7),
]),
]),
]),
]);
I'm struggling to write a function that would produce the output, can anyone help? Any modern object oriented language would be fine really, c#, js, dart, c++.
If I understand correctly you are looking for functions named Ands, Ors and single that will give the desired result. The format of the desired result is a 2D array where the inner arrays list atomic values that are AND'ed, and the outer array lists items that are OR'ed.
Each of those functions should return that format, also single. So for instance, single(1) should return [[1]].
The Ors function should just concatenate the 2D items it gets as argument into a longer 2D array. So if for instance, Ors gets two items: [[1,2]] and [[3,4],[5,6]] then the return value should be [[1,2],[3,4],[5,6]].
The more complex one is Ands: it should perform a Cartesian product on the arguments it gets.
Here is an implementation in JavaScript. The notation of the input is a bit different, as items: as function argument would be invalid syntax. We can just pass each item as a separate argument and use spread syntax:
function single(i) {
return [[i]];
}
function Ands(first, ...rest) {
// Cartesian product, using recursion
if (!rest.length) return first;
let restResult = Ands(...rest);
let result = [];
for (let option of first) {
for (let restOption of restResult) {
result.push([...option, ...restOption]);
}
}
return result;
}
function Ors(...items) {
return items.flat(1); // Reduces 1 level of array depth (from 3 to 2)
// Alternative syntax to get the same result:
// return [].concat(...items)
}
var andsOrs =
Ands(
single(1),
Ors(
single(2),
single(3),
Ands(
single(4),
single(5),
Ors(
single(6),
single(7),
),
),
),
);
console.log(andsOrs);
I'm using ASP.NET Core 2.1. I have settings in appsettings.json and I bind them to classes using the options pattern. I want to override some of them in appsettings.Production.json.
Overriding is supported according to the docs, and works for me generally.
But it doesn't work for arrays.
appsettings.json:
"MySectionOuter": {
"MySectionInner": [
{
"foo": "1",
"bar": "2",
"baz": "3"
},
{
"foo": "a",
"bar": "b",
"baz": "c"
}
]
}
My overrides in appsettings.Production.json
"MySectionOuter": {
"MySectionInner": [
{
"bar": "4",
},
{
"baz": "d"
}
]
}
However that doesn't work - it adds rather than replaces.
I read that the array is syntactic sugar for a key-value store. So I also tried this:
"MySectionOuter": {
"MySection:1": {
"bar": "4",
},
"MySection:2": {
"baz": "b",
}
}
But that also doesn't work.
What is the correct syntax?
UPDATE
The comments show I haven't explained properly. What I want is like this:
During development:
element1: foo=1
element1: bar=2
element1: baz=3
element2: foo=a
element2: bar=b
element2: baz=c
During production:
element1: foo=1
element1: bar=2
element1: baz=4 // this was changed
element2: foo=a
element2: bar=b
element2: baz=d // this was changed
In fact, there are no arrays there when the configuration is built. It's just a key-value pair dictionary. So you end up with string keys, something like
"mysectionouter:mysectioninner:0:foo" = 1.
So when in your config you define an array, the following happens:
appsettings.json:
"mysectionouter:mysectioninner:0:foo" = 1
"mysectionouter:mysectioninner:0:bar" = 2
appsettings.production.json:
"mysectionouter:mysectioninner:0:bar" = new1
result:
foo = 1
bar = new1
So it's just index-based, and next configuration just overrides a key. In your second example, you achieve nothing but changing the index. Representation would be:
"mysectionouter:mysectioninner:1:bar" = new1
So back to your question: arrays are tricky in appsettings, and though supported, are generally hard and not intuitive to use.
By index you may get a weird merge of two not related objects, if you define different sets of settings in your files, like settings A and B in the first config, and C in second, you will get C and B in the result, and you likely don't want to have B at all. Worse still, you can get a mix of A and C if you define only some fields of each object.
I'd recommend using some other files for storing this kind of information. You can also break in the debugger just where the configuration is loaded and see for yourself how these keys are build to get more insight.
According to this blog post: https://www.paraesthesia.com/archive/2018/06/20/microsoft-extensions-configuration-deep-dive/
It's not possible to remove configuration items with a provider.
You can add configuration at override time, but you can’t remove things. The best you can do is override a value with an empty string.
Instead you should only fill as little information as needed in the appsettings.config and fill the appropriate settings in a more specialized settings file. E.g. appsettings.Development.config or your appsettings.Production.config. Or as suggested in the blog post:
Since you can’t remove things, specify as little configuration as possible and behave correctly using defaults in your code when configuration isn’t there.
I was actually having a similar issue in dotnet 6, when trying to merge arrays from multiple appsettings, when I stumbled across this thread.
The solution was actually way simpler then thought.
Microsoft.Extensions.Configuration merges arrays through the index:
{ foo: [1, 2, 3] } + { foo: [4, 5] } = { foo: 4, 5, 3 }
But we want to be able to declare which entries override others and which ones should be added to the list. And we do this by declaring a GUID as dictionary key instead of an array.
{
"foo": {
"870622cb-0372-49f3-a46e-07a1bd0db769": 1,
"cbb3af55-94ea-41a5-bbb5-cb936ac47249": 2,
"9410fcdc-28b3-4bff-bfed-4d7286b33294": 3
}
}
+
{
"foo": {
"cbb3af55-94ea-41a5-bbb5-cb936ac47249": 4,
"1c43fa78-b8db-41f8-809d-759a4bc35ee2": 5,
}
}
=
{
"foo": {
"870622cb-0372-49f3-a46e-07a1bd0db769": 1,
"cbb3af55-94ea-41a5-bbb5-cb936ac47249": 4, /*2 changed to 4 because key equals*/
"9410fcdc-28b3-4bff-bfed-4d7286b33294": 3
"1c43fa78-b8db-41f8-809d-759a4bc35ee2": 5, /*while 5 added to the list*/
}
}
This may seem inconventient at first, because one would think, that
((IConfiguration)config).GetSection("foo").Get<int[]>();
Throws some kind of invalid type exception, since a Guid is not what we know as array index.
But it can actually (implicitly!) return the merged "foo" section above as int[].
I'm studying a book with Membership topic in ASP.NET MVC and I found syntax, I cannot trace (and not explained in the book), which is:
new[] {"string"}
like in:
Roles.AddUsersToRoles(new[] {userName}, new[] {roleName});
Per MDSN library I see Roles.AddUsersToRoles method takes two string arrays as arguments, so likely this is a shorthand or would this have some additional functionality?
It is Implicitly Typed Arrays syntax.
You can create an implicitly-typed array in which the type of the
array instance is inferred from the elements specified in the array
initializer.
This
string[] stringArray = new[] {"string"};
is same as :
string[] stringArray = new string[] {"string"};
Other thing to note, the method Roles.AddUsersToRoles accepts two parameters of string type array (and not a string).
public static void AddUsersToRoles(
string[] usernames,
string[] roleNames
)
new string[1] { "string" }
You can omit the array size because the compiler can count the number of elements for you:
new string[ ] { "string" }
You can also omit the array element type because the compiler can infer it from the values provided:
new [ ] { "string" }
But do not get this mixed up with initializers for anonymous types. These do not have the angle brackets [] after new:
new { StringProperty = "string" }
or:
// string StringProperty;
new { StringProperty }
Is there any possibility to decode Morse code to text if the code is in following format(without any white spaces):
-.-..--.....-...--..----.
Normally it looks like that,
- .-. .- -. ... .-.. .- - .. --- -.
t r a n s l a t i o n
but is it possible, to get the same text from Morse code without white spaces?
This is possible to do, but it becomes problematic as you end up generating a large number of possible options.
First start with a Morse mapping:
private Dictionary<string, string> map = new Dictionary<string, string>()
{
{ ".-", "a" },
{ "-...", "b" },
{ "-.-.", "c" },
{ "-..", "d" },
{ ".", "e" },
{ "..-.", "f" },
{ "--.", "g" },
{ "....", "h" },
{ "..", "i" },
{ ".---", "j" },
{ "-.-", "k" },
{ ".-..", "l" },
{ "--", "m" },
{ "-.", "n" },
{ "---", "o" },
{ ".--.", "p" },
{ "--.-", "q" },
{ ".-.", "r" },
{ "...", "s" },
{ "-", "t" },
{ "..-", "u" },
{ "...-", "v" },
{ ".--", "x" },
{ "-..-", "y" },
{ "-.--", "z" },
{ "--..", " " },
};
Then this function can produce the possible decodings:
public IEnumerable<string> DecodeMorse(string morse)
{
var letters =
map
.Where(kvp => morse.StartsWith(kvp.Key))
.Select(kvp => new
{
letter = kvp.Value,
remainder = morse.Substring(kvp.Key.Length)
})
.ToArray();
if (letters.Any())
{
var query =
from l in letters
from x in DecodeMorse(l.remainder)
select l.letter + x;
return query.ToArray();
}
else
{
return new [] { "" };
}
}
Now, given a shorter version of your input morse, "-.-..--....", I got 741 possible strings. Here's the cut down version:
cabe
cadee
cadi
…
tranie
trans
trateeee
…
trxii
trxse
It includes "trans" so it seems to be working.
Running on the full string produces 5,914,901 possible with "translation" as one of the possibilities.
Incidentally, there were 4,519 possible strings that simply started with "trans". How humans could do this on the fly is amazing!
What you are proposing isn't really possible.
You will not be able to tell where one letter ends and the next begins. How will you be able to tell the difference between letters? Will the first letter be -, -., or -.-?
There is no doubt in my mind that given a sufficiently advanced algorithm, and sufficient context around each letter, that it is possible to get a high level of accuracy. However the problem approaches AGI-level difficulty the greater accuracy that you require, because this is one of the skills (fast pattern matching in language) that humans are particularly good at and machines are nowhere near as good at (yet). The reason for that, is that broader context that makes pattern matching possible for humans includes not just possible words, but semantics and the overall meaning of the story, and mapping that to model of the world that makes sense. This is something that is extremely difficult to program a computer to do. Also the human brain is massively parallel.
Also, it is fairly trivial to prove that a general perfect solution is impossible (perfect accurate translation for every possible input string). For example, consider simply the short string ".--", that could mean "at" or "em", both valid English words.
You need to know where the characters start and end. Take, for instance:
...---...
If you divide it one way, you get:
... --- ... = SOS
However, if you divide it differently, you may get:
. .. - -- . .. = EITMEI
So, is it possible? Technically, yes, it's possible. However, you would have a huge number of possible solutions that would take a long time to identify and translate. With a database of commonly seen words, you might be able to make this a bit smarter, but it would still be a best-effort.
var movieNext = new string[,]
{
{ "superhero", "action", "waltdisney", "bat"},
{"superhero", "action", "marvel",""},
{"history", "action", "malay", "" },
{"malay", "novel", "", ""},
{"history", "bat", "", ""}
};
The above code is a multidimensional array, which stores a sequence of movie's keyword. Is there a way to implement this without having to put the blank strings in the array initialization?
For example you can see in the above code, I have to put the blank string "" to fill up the array.
You could use a jagged array instead.
string[][] movieNext = new string[][] { { etc... } }.
You can consider C# jagged array (though they are different from multi-dimensional arrays).
string[][] movieNext = {
new [] { "superhero", "action", "waltdisney", "bat"},
new [] {"superhero", "action", "marvel"}, <and so on>
};
If you want to stick with multi-dimensional arrays, you have to initialize the values individually. If you don't provide any string value for any of the index (i,j) by default it will be null.
I suggest never to use two-dimensional arrays. They have practically no support in the API (you'll be hard pressed to find a method that accepts a two-dimensional array as a parameter), and cannot be cast to IEnumerable<T> or similar well-supported interface. As such, you can really use them only in the most local of scopes.
Instead, I suggest you use something castable to IEnumerable<IEnumerable<string>>. Oh, another tip. Check this out. Specifically,
To initialize a Dictionary, or any collection whose Add method takes multiple parameters, enclose each set of parameters in braces as shown in the following example.
Thus, the following will work:
class Program
{
static void Main(string[] args)
{
var d = new ManyList()
{
{"Hi", "Good", "People", "None", "Other"}
{"Maybe", "Someone", "Else", "Whatever"}
};
Console.Read();
}
}
class ManyList : List<string>
{
public void Add(params string[] strs)
{
Console.WriteLine(string.Join(", ", strs));
}
}
This might help you clean up your syntax a bit.