Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
In a code review of a component library, I found syntax where some calculations for days per month are needed.
The simplified syntax is something like:
int preDays = (new int[] { 0, 1, 2, 3, 4, 5, 6 })[3] - 2;
Where [3] and -2 are variables. In the above example, the result of preDays is 1.
Could somebody please explain how we come to this result?
Break down the code into its individual pieces. Just like in math, we perform operations inside the parenthesis first, so you're creating an array of integers with the values 0 through 6. Next, the code looks at index 3 (arrays in C# are 0-based). The value at index 3 is 3. Lastly, we subtract 2 from 3 to get 1 and assign it to preDays.
You can think of it like this:
int[] myArray = { 0, 1, 2, 3, 4, 5, 6};
int myValue = myArray[3]; // Value is 3
int preDays = myValue - 2; // Value is 1
Does this help:
var array = new int[] { 0, 1, 2, 3, 4, 5, 6 };
int value = array[3]; //3
int preDays = value - 2; //1
This one's quite easy in my opinion:
within the () there's a new anonymous array defined. An array which consists of seven elements being 0,1,2,3,4,5 and 6. From this array you take the 4th element.
([3] refers to the fourth element as counting starts from [0] referring to the first element).
The fourth element of the array is 3, so the expression (new int[] { 0, 1, 2, 3, 4, 5, 6 })[3] resolves to 3. Subtracting 2 from 3 makes preDays to be filled with 1.
you are creating an array an making an arithmetic calculation on the same line and given that
index in c# has a zero as base so if you count 0,1,2,3 you will get a value 3 in the 4 case of the array so 3 minus 2 you will get 1
So take it like that
var myArray = new int[] { 0, 1, 2, 3, 4, 5, 6 };
int myValue = array[3]; //3
int preDays = value - 2;
In int preDays = (new int[] { 0, 1, 2, 3, 4, 5, 6 })[3] - 2;
(new int[] { 0, 1, 2, 3, 4, 5, 6 }) will create temporary integer array of size 7 and with values(0, 1, 2, 3, 4, 5, 6).
(new int[] { 0, 1, 2, 3, 4, 5, 6 })[3] will extract 4th item(item with index 3) i.e value 3.
(new int[] { 0, 1, 2, 3, 4, 5, 6 })[3] - 2 will perform 3 - 2 = 1.
Related
Sorry if the header made you confused.
This thread looks similar header but that is actually different Selecting some lists from a list of lists.
I want to Select some lists in many lists that look like a list
Sample:
// data source
List<List<int>> sources = new List<List<int>>();
sources.Add(new List<int>(){1, 2, 3, 4});
sources.Add(new List<int>(){1, 2, 3, 4, 5});
sources.Add(new List<int>(){1, 2, 3, 4, 5, 6});
sources.Add(new List<int>(){1, 2, 99, 3, 4, 5, 6});
sources.Add(new List<int>(){1, 3, 99, 2, 4, 5});
sources.Add(new List<int>(){5, 4, 3, 2, 1});
sources.Add(new List<int>(){1, 2, 4, 5, 6});
sources.Add(new List<int>(){1, 2, 69, 3, 4, 5});
// the list that we want to find lists similar to this
List<int> current = new List<int>() {1, 2, 3, 4, 5};
The list contain not-important element, can be ignored. Updated! In the case its elements are not appeared in current:
List<int> flexible = new List<int>() {99, 66, 123123, 2};// <= updated!
The function I want to write:
void FilterA(List<int> current, List<List<int>> sources, List<int> flexible) {}
How to make FilterA output these list (Lists chosen)? Printing functions are not required.
Lists chosen
1 2 3 4 5 // exactly the same !
1 2 3 4 5 6 // same first 5 elements, the rests are not important
1 2 99 3 4 5 6 // 99 is in flexible list, after ignored that is 1 2 3 4 5 6
// Updated! Ignore 99 because it is not in list current
Lists ignored
1 2 3 4 // missing 5 in current
1 3 99 2 4 5 // 99 is in flexible list, after ignored that is 1 3 2 4 5
5 4 3 2 1 // wrong order
1 2 4 5 6 // missing 3 in current
1 2 69 3 4 5 // 69 is not in flexible list
Thank you very much!
--- Updated ---
If elements in list flexible appeared in list current, they must not be excluded.
The answer of #Sweeper is nice.
p/s: In the case not any element of flexible appear in current, #TheGeneral 's answer is great, runs great performance.
Update after clarification
The premise is, remove flexible with Except, Take n to then compare with SequenceEqual.
Note : All three methods have linear time complexity O(n)
var results = sources.Where(x =>
x.Except(flexible)
.Take(current.Count)
.SequenceEqual(current));
Output
1, 2, 3, 4, 5
1, 2, 3, 4, 5, 6
1, 2, 99, 3, 4, 5, 6
Full demo here
Additional Resources
Enumerable.Except
Produces the set difference of two sequences.
Enumerable.Take
Returns a specified number of contiguous elements from the start of a
sequence.
Enumerable.SequenceEqual
Determines whether two sequences are equal according to an equality
comparer.
You should write a method that determines whether one list (candidate) should be chosen:
public static bool ShouldChoose(List<int> candidate, List<int> current, List<int> flexible) {
int candidateIndex = 0;
foreach (int element in current) {
if (candidateIndex >= candidate.Count) {
return false;
}
// this loop looks for the next index in "candidate" where "element" matches
// ignoring the elements in "flexible"
while (candidate[candidateIndex] != element) {
if (!flexible.Contains(candidate[candidateIndex])) {
return false;
}
candidateIndex++;
}
candidateIndex++;
}
return true;
}
Then you can do a Where filter:
var chosenLists = sources.Where(x => ShouldChoose(x, current, flexible)).ToList();
foreach (var list in chosenLists) {
Console.WriteLine(string.Join(", ", list));
}
This works for me:
var results =
sources
.Where(source => source.Except(flexible).Count() >= current.Count())
.Where(source => source.Except(flexible).Zip(current, (s, c) => s == c).All(x => x))
.ToList();
Given a 1D array,
double[] arr = { 4, 3, 2, 8, 7, 6, 1 };
I want to get values from 2nd index till last and want to store the array in a variable.
Want to get something like this:
new_arr = {3, 2, 8, 7, 6, 1 }; //first element sliced
You can use C# 8 indices and ranges feature
double[] arr = { 4, 3, 2, 8, 7, 6, 1 };
var slice = arr[1..];
It'll return all items from index 1 till the end of array and give you an expected slice {3, 2, 8, 7, 6, 1 }. Again, it works only with C# 8 and .NET Core 3.x.
For earliest versions of C# you should do this by yourself, using Array.Copy for example or System.Linq
double[] arr = { 4, 3, 2, 8, 7, 6, 1 };
var slice = arr.Skip(1).ToArray();
If you are using C# 8, you can use Indices & Range. It goes something like this:
var newArray = oldArray[1..]; // Takes everything from index 1 until the end.
You can use Linq to skip the fist item and take the rest. This will give you the sequence:
arr.Skip(1);
Which you can convert to a new array like this:
var new_arr = arr.Skip(1).ToArray();
I have an array of ints, that It should like the following:
7 3 2 4 5 6 1 9 10 8 Values
[1 2 3 4 5 6 7 8 9 10] Order In Array
This values should change its order, and every value, it's a random option, for example:
If it chooses that the first value is 6, it chooses the color blue, then, it goes to the second value, if the value is 4, it chooses green.
Every number is equal to a color.
I've been thinking that I can use an if conditional, but I dont know if there's a property to check the value, because if I do a if conditional for each option, it could take like 100+ lines of code!.
Do you have any idea of how can I improve it?.
You can do this almost in one line :
var rnd = new Random();
var orderedNumbers = new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
var randomizedNumbers = orderedNumbers.OrderBy(c => rnd.Next()).ToArray();
it's a insertion sort algorithm
I understand forwarding the greatest no to next index but cant understand when it moves forward how its previous position (index) is being taken by the smaller number that was just compare e.g in list [2,1] 2 moves to next index by list[j+1]=list[j]; but how 1 moves backward or to previous index
//unsorted array
int[] list = new int[] { 5, 2, 4, 6, 1 };
// the key element being sorted
int key;
//
//start looping starting from the second element
for (int i = 1; i < list.Length; i++)
{
key = list[i];//store the key
int j = i - 1;//get the previous index
//
//loop until you meet a smaller number or 0
while (j >= 0 && list[j] > key)
{
//move the greater number forward
list[j + 1] = list[j];
// Decrementing
j--;
}
//set the key in the proper index
list[j + 1] = key;
}
That is done in the last line inside the loop. After moving one or more (or even zero) items forward, the current value is put in the correct position.
For example, if you have sorted the array up to the last item, and it looks like this:
2, 4, 5, 6, 1
The value 1 is copied into the key variable, then items are copied forward one by one:
2, 4, 5, 6, - <- the empty slot here still contains 1, but it's unused
2, 4, 5, -, 6 <- the empty slot here still contains 6, but it's unused
2, 4, -, 5, 6
2, -, 4, 5, 6
-, 2, 4, 5, 6
Now the value from the key variable is placed where the last item was copied from:
1, 2, 4, 5, 6
The theory behind the insert sort is to take items from one array and insert into a new array. The implementation that you are using is only using a single array, and you can think of it as divided into a sorted part and an unsorted part. The sorted part starts out with the size zero:
[][ 5, 2, 4, 6, 1 ]
when the array is sorted, items are picked from the unsorted part and are inserted at the right place in the sorted part. The sorted part grows and the unsorted part shrinks, until the unsorted part is empty:
[ 5 ][ 2, 4, 6, 1 ]
[ 2, 5 ][ 4, 6, 1 ]
[ 2, 4, 5 ][ 6, 1 ]
[ 2, 4, 5, 6 ][ 1 ]
[ 1, 2, 4, 5, 6 ][]
There are TWO lists/arrays
The declaration at the top...
int[] list = new int[] { 5, 2, 4, 6, 1 };
Says to make a list/array of integer format called X
X being whatever name you give it...
In this case the lists/arrays are list/array I[] and list/array J[]
So it (most likely) could be READING from one list/array maybe the I[] list/array
and assigning the SORTED values into the other list/array maybe the J[] list/array
Let's say that I have an array of strings like this:
1, 2, 3, 4, 5, 6, 7, 8
and I want to shift the elements of the array such that
The first element always remains fixed
Only the remaining elements get shifted like so ...
The last element in the array becomes the 2nd element and is shifted through the array with each pass.
Pass #1: 1, 2, 3, 4, 5, 6, 7, 8
Pass #2: 1, 8, 2, 3, 4, 5, 6, 7
Pass #3: 1, 7, 8, 2, 3, 4, 5, 6
Pass #4: 1, 6, 7, 8, 2, 3, 4, 5
Any assistance would be greatly appreciated.
Because this looks like homework, I'm posting an unnecessary complex, but very hip LINQ solution:
int[] array = new int[] { 1, 2, 3, 4, 5, 6, 7, 8 };
int[] result = array.Take(1)
.Concat(array.Reverse().Take(1))
.Concat(array.Skip(1).Reverse().Skip(1).Reverse())
.ToArray();
Probably the fastest way to do this in C# is to use Array.Copy. I don't know much about pointers in C# so there's probably a way of doing it that's even faster and avoids the array bounds checks and such but the following should work. It makes several assumptions and doesn't check for errors but you can fix it up.
void Shift<T>(T[] array) {
T last = array[array.Length-1];
Array.Copy(array, 1, array, 2, array.Length-2);
array[1]=last;
}
EDIT
Optionally, there is Buffer.BlockCopy which according to this post performs fewer validations but internally copies the block the same way.
Because this looks like homework, I'm not going to solve it for you, but I have a couple of suggestions:
Remember to not overwrite data if it isn't somewhere else already. You're going to need a temporary variable.
Try traversing the array from the end to the beginning. The problem is probably simpler that way, though it can be done from front-to-back.
Make sure your algorithm works for an arbitrary-length array, not just one that's of size 8, as your example gave.
Although sounds like homework like others suggest, if changing to a List<>, you can get what you want with the following...
List<int> Nums2 = new List<int>();
for( int i = 1; i < 9; i++ )
Nums2.Add(i);
for (int i = 1; i < 10; i++)
{
Nums2.Insert( 1, Nums2[ Nums2.Count -1] );
Nums2.RemoveAt(Nums2.Count -1);
}
Define this:
public static class Extensions
{
public static IEnumerable<T> Rotate<T>(this IEnumerable<T> enuml)
{
var count = enuml.Count();
return enuml
.Skip(count - 1)
.Concat(enuml.Take(count - 1));
}
public static IEnumerable<T> SkipAndRotate<T>(this IEnumerable<T> enuml)
{
return enum
.Take(1)
.Concat(
enuml.Skip(1).Rotate()
);
}
}
Then call it like so:
var array = new [] { 1, 2, 3, 4, 5, 6, 7, 8 };
var pass1 = array.SkipAndRotate().ToArray();
var pass2 = pass1.SkipAndRotate().ToArray();
var pass3 = pass2.SkipAndRotate().ToArray();
var pass4 = pass3.SkipAndRotate().ToArray();
There's some repeated code there that you might want to refactor. And of course, I haven't compiled this so caveat emptor!
This is similar to Josh Einstein's but it will do it manually and will allow you to specify how many elements to preserve at the beginning.
static void ShiftArray<T>(T[] array, int elementsToPreserve)
{
T temp = array[array.Length - 1];
for (int i = array.Length - 1; i > elementsToPreserve; i--)
{
array[i] = array[i - 1];
}
array[elementsToPreserve] = temp;
}
Consumed:
int[] array = { 1, 2, 3, 4, 5, 6, 7, 8 };
ShiftArray(array, 2);
First pass: 1 2 8 3 4 5 6 7