How to slice elements from 2nd item in a c# array? - c#

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();

Related

Efficient way to replace int in list with first occurrence index

I am looking for a way to replace every int element in a list with the index of its first occurrence in a separate Distinct list. For example, take the following list:
<50, 2, 4, 5, 43, 42, 44, 14, 50, 44, 23, 2, 16, 4, 5, 23, 33 ... >
The distinct list would read like this:
<50, 2, 4, 5, 43, 42, 44, 14, 50, 23, 33 ... >
I would like for the list to read as follows:
<0, 1, 2, 3, 4, 5, 6, 7, 0, 6, 8, 1, 9, 3, 4, 8, 10 ...>
I am new to LINQ operators, but I have the following code:
//Retrieve original list:
List<int> SubFaceList = FaceList.GetRange (faceBounds [fb], faceBounds [fb + 1]);
// Get unique face list entries:
List<int> UniqueFaceList = SubFaceList.Distinct ().ToList ();
//Replace values with first ocurrence:
List<int> RestructuredList = SubFaceList.Select ((vx,ix) => UniqueFaceList.IndexOf(vx)).ToList();
I am doing this, in order to split up a large Collada triangular 3D mesh, into smaller submeshes. The arrays are face construction order, which reference an index of vertices in a separate array, so numbers could be referenced multiple times in the face array. However, upon executing my code, some meshes take upwards of 30 minutes to process.
I also have the following code, which extracts the given vertices from the main vertex array, which does not seem to suffer from the same crippling inefficiency:
List<Vector3> subVertices = Vertices.Where ((vx, ix) => UniqueFaceList.Contains (ix)).Select (vx => vx).ToList();
Am I going about this wrong, and is there a potential way that I could extract the index based on the current vertex being processed in this statement? I know there has to be a more efficient way to get the information that I need, but I am not quite sure how.
It's possible with LINQ, but if you want maximum performance, you could use Dictionary and simple for / foreach loop (you'll find that the code is not so bigger than the most efficient LINQ solution):
var indexMap = new Dictionary<int, int>();
var RestructuredList = new List<int>(SubFaceList.Count); // final capacity
foreach (var item in SubFaceList)
{
int index;
if (!indexMap.TryGetValue(item, out index))
indexMap.Add(item, index = indexMap.Count);
RestructuredList.Add(index);
}
Store value and index to dictionary.
var faceList = new List<int>{ 50, 2, 4, 5, 43, 42, 44, 14, 50, 44, 23, 2, 16, 4, 5, 23, 33};
var uniqueList = new Dictionary<int,int>();
var restructuredList = new List<int>();
var i = 0;
faceList.ForEach(f =>
{
if (uniqueList.ContainsKey(f))
{
restructuredList.Add(uniqueList[f]);
return;
}
restructuredList.Add(i);
uniqueList.Add(f, i++);
});

C# Order of Operations Syntax Explanation [closed]

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.

Sorting range of list using LINQ

I was wondering if it is possible to do ranged sort using LINQ, for example i have list of numbers:
List< int > numbers = new List< int >
1
2
3
15 <-- sort
11 <-- sort
13 <-- sort
10 <-- sort
6
7
etc.
Simply using numbers.Skip(3).Take(4).OrderBy(blabla) will work, but it will return a new list containing only those 4 numbers. Is is somehow possible to force LINQ to work on itself without returning a new "partial" list or to receive complete one with sorted part?
Thanks for any answer!
Try something like this:
var partiallySorted = list.Where(x => x < 11)
.Concat(list.Where(x => x >= 11 && x <=15).OrderBy(/*blah*/)))
.Concat(list.Where(x => x > 15));
List<int> list = new List<int>() {1,2,3,15,11,13,10,6,7};
list.Sort(3, 4,Comparer<int>.Default);
Simply get the required range based on some criteria and apply the sort on the resultant range using Linq.
List<int> numbers = new List<int>() { 15, 4, 1, 3, 2, 11, 7, 6, 12, 13 };
var range = numbers.Skip(3).Take(4).OrderBy(n => n).Select(s => s);
// output: 2, 3, 7, 11
No, the Linq extension methods will never modify the underlying list. You can use the method List<T>.Sort(int index, int counter, IComparer<T> comparer) to do an in-place sort:
var list = new List<int> {1, 2, 3, 15, 11, 13, 10, 6, 7};
list.Sort(3, 4, null);
Use this for default inline List Sort:
Syntax: List.Sort(start index, number of elements, Default Comparer)
List<int> numbers = new List<int> { 1, 2, 3, 15, 11, 13, 10, 6, 7 };
numbers.Sort(3, 6, Comparer<int>.Default);
If you want to sort by [properties/attributes] of the element or precisely something else use the below method,
I had sorted the string by number of characters, and also from 2nd element to end of List.
Syntax: List.Sort(start index, number of elements, Custom Comparer)
List<string> str = new List<string> { "123", "123456789", "12", "1234567" };
str.Sort(1, str.Count - 1, Comparer<string>.Create((x, y) => x.Length.CompareTo(y.Length)));

How do I shift items in an array in C#?

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

.NET 3.5: How to remove from list using the 3.5 functions

I have a List with objects. Each object has an ID. I want to remove all the objects which their IDs appear in a given collection.
I know that in 3.5 there are functions such as RemoveAll that can facilitate the search and remove.
the function's prototype is:
internal SomeObject removeFromMe(Dictionary<string, string> idsToRemoveAreTheKeys)
What's the best way to remove from the list?
Thanks.
list.RemoveAll(item => idsToRemoveAreTheKeys.ContainsKey(item.ID));
This checks each item in the list once, and performs a key lookup in the dictionary, so it's roughly O(N) because key lookups are fast.
If you looped through the keys, you'd have to do a linear search through the list each time, which would require O(N*M), where M is the number of keys in the dictionary.
For List you can do this:
Dim sam As New List(Of Integer) From {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
sam.RemoveAll(Function(x) x Mod 2 = 0)
var sam = New List<int> {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
sam.RemoveAll( x => x % 2 = 0)

Categories