How can we delete all array elements between 2 numbers?
For example : The array is {2,6,3,6,8,2,7,2}
The user writes in two numbers, let's say 2 and 4.
That causes the program to delete every array elements between the 2nd and 4th position.
In this case, it deletes : 3,6,8
You cannot delete items from an array. But you can create a new array that contains only the items that you want to keep. In your case you can use the following:
int[] array = {2, 6, 3, 6, 8, 2, 7, 2};
array = array.Where((_, i) => i < 2 || i > 4).ToArray();
By the way, if you use a List instead of an array, then you can remove items. Consider the following example:
List<int> list = new List<int>() {2, 6, 3, 6, 8, 2, 7, 2};
for(int i = 4; i >= 2 ; i--)
{
list.RemoveAt(i);
}
For lists, you can use RemoveRange to do exactly that. It’s just that instead of the (inclusive) end index, you need to pass the number of elements you want to delete. So for inclusive indexes start and end it would look like this:
list.RemoveRange(start, end - start + 1);
For arrays, you cannot really do this as once created arrays have a fixed size. If you really need an array, you could create a list from the array, remove the items, and then create an array again using ToArray.
As Yacoub Massad mentioned in his answer: You cannot delete items from an array. But you can create a new array that contains only the items that you want to keep. In this case I would use linq, it's super easy:
int[] array = {2, 6, 3, 6, 8, 2, 7, 2};
int x = 2;
int y = 4;
var array1 = array.ToList()
.Take(x).Concat(array.ToList().Skip(x+y-1))
.ToArray();
foreach(var i in array1)
{
Console.Write(i);
Console.Write(',');
}
Result:
2,6,2,7,2,
DotNetFiddle Example
Related
I would like to create a PriorityQueue to store int[]. The first element in the array is gonna be the criteria for the comparisons.
I could do that easily in Java, though I could not convert it to C#. Could you please guide me?
Priority queues don't work the same way in both languages. What you're trying to do is the Java way of giving PQ a lambda (function) to compare any two elements. In C#, you give each element a priority when adding it to the queue, and then make a comparer to compare different priorities.
PriorityQueue<int[], int> pq = new(Comparer<int>.Create((a, b) => a - b));
// The Comparer compares the *priorities*, not the elements
pq.Enqueue(new int[] { 1, 2, 3, 4 }, 5);
pq.Enqueue(new int[] { 1, 2, 3, 4 }, 0); // This has more priority
while (pq.TryDequeue(out int[]? arr, out int priority))
{
Console.WriteLine(priority); // 0; 5
}
You may be interested in just a simple List and LINQ:
using System.Linq; // at the top of your code to include LINQ
List<int[]> list = new();
list.Add(new int[] { 1, 2, 3, 4 });
list.Add(new int[] { 5, 2, 3, 4 });
IEnumerable<int[]> ordered = list.OrderBy(x => x[0]); // orders by the first element
Consider the int array below of n elements.
1, 3, 4, 5, 7. In this example the second last item is 5. I want to get the number of elements in this array before the second last value. There are 3 elements before the second last element. I will store the result in an int variable to use later. We obviously take into account that the array will have more than two element all the time.
This array will have different size everytime.
How can I achieve this in the most simplistic way?
The answer will always be n-2, so a very quick solution is to use .Length property and to subtract 2.
You can use Range from C# 8:
int[] arr = new int[]{1, 3, 4, 5, 7};
int[] newArr = arr.Length>=2 ? arr[..^2] : new int[0];
This will return all elements except the last 2, or an empty array if the lenght is less than 2. If it is guaranteed that the array will always have more than 2 elements, then you can simplify:
int[] newArr = arr[..^2];
If you are only interested about the quantity of the numbers then .Length-2 is the best way as it was stated by others as well.
If you are interested about the items as well without using C# 8 features then you can use ArraySegment (1).
It is really powerful, like you can reverse the items without affecting the underlying array.
int[] arr = new int[] { 1, 3, 4, 5, 7 };
var segment = new ArraySegment<int>(arr, 0, arr.Length - 2);
var reversedSegment = segment.Reverse(); //ReverseIterator { 4, 3, 1 }
//arr >> int[5] { 1, 3, 4, 6, 7 }
Please bear in mind that the same is not true for Span (2).
var segment = new Span<int>(arr, 0, arr.Length - 2);
segment.Reverse();
//arr >> int[5] {4, 3, 1, 6, 7 }
There is a ReadOnlySpan, which does not allow to perform such operation as Reverse.
If you would need that then you have to manually iterate through that in a reversed order.
So, i have a set of integers in an list
public List<int> numbers = new List<int>() { 3, 7, 6, 9, 8, 10, 11 }
what i am wanting to do is change those numbers so they are ordered between 0 and 6, to set as siblingindexs.
and then would be changed to become
public List<int> newArrangedNumbers = new List<int>() {0, 2, 1, 4, 3, 5, 6}
But im really not sure how to do this... Anyone know?
P.S. i cant rearrange the numbers because then i would lose track of the game objects since the numbers themselves aren't actually in an array, but i have gameobjects in an array, and i find the "SortIndex" of each gameobject, which are the numbers from above, the order of the numbers in the array is actually the order of GameObjects in the array, which i need to keep the same.
Edit: i also cannot change them to float values because for some reason, when using SetSiblingIndex(int), you have to integers, you cant use floats
Edit 2: i am NOT trying to sort the numbers, i am trying to CONVERT the numbers from 3-11 into 0-6 in ORDER
From:
{3, 7, 6, 9, 8, 10, 11}
To:
{0, 2, 1, 4, 3, 5, 6}
Edit 3: Here is my script for testing
List<int> Indexs = new List<int>() { 4, 7, 56, 9, 65, 67, 8, 3, 6 };
var sorted = Indexs.Select((x, i) => new KeyValuePair<int, int>(x, i)).OrderBy(x => x.Key).ToList();
List<int> newArrangedNumbers = sorted.Select(x => x.Value).ToList();
for(int i = 0; i < newArrangedNumbers.Count; i++)
{
Debug.Log(Indexs[i] + " : " + newArrangedNumbers[i]);
}
When i only had 7 (0-6) indexs in the "Indexs" List it worked fine, but when i added any more, it started giving me the incorrect numbers
This is what it gives with this
Here is a good method to achieve your desired output from this stack form C# Sort list while also returning the original index positions?
The modified code for your solution is below.
//The original list
List<int> numbers = new List<int>() { 3, 7, 6, 9, 8, 10, 11 };
var sorted = numbers
.Select((x, i) => new KeyValuePair<int, int>(x, i))
.OrderBy(x => x.Key)
.ToList();
//The sorted list
List<int> numbersSorted = sorted.Select(x => x.Key).ToList();
//List of indexes sorted based on the list above
List<int> newArrangedNumbers = sorted.Select(x => x.Value).ToList();
Edit
Since you sort the list, but also retrieve the sorted indexes based on the list you just sorted, you aren't going to have any mixup with your game objects.
It sounds like you want to find positions of each element in a sorted list of the same items.
So sort and find where element is and assign the index. Code sample below assumes unique numbers:
var sorted = numbers.OrderBy(x=>x).ToArray();
var result = new int[numbers.Count];
for (var i = 0; i < numbers.Count; i++)
{
var index = number.IndexOf(sorted[i]);
result[index] = i;
}
Notes
for anything about 5-10 items I'd use dictionary instead of IndexOf if you want to stick with this code.
if numbers are not unique or performance is critical you need to use solution by Aaron Jones that eventually will track original indexes even if it is harder to understand.
I am writting algorithm for intersection of two arrays A and B , I want an optimized solution in terms of space complexity and time complexity.
I have written algorithm and it works fine but i want to know if there is any more optimal solution then this exist or if someone could provide me.
What i do is:
(1) Find the Smallest size array among two.
(2) The new array wil be of size allocated size equal to smaller size array
(3) From smaller size array i go and compare with each element in bigger array if it exists one ,i get it in third array"C" and break it right there (because we need to find intersection, even if it repeats 100 times after
we don't care for us only one existence is enough to put in third array). At the same time we also have to check if the element in smaller array which to be compared with all elements in bigger array already exist in third array, Example A=[0,1,1], B[0,1,2,3].
Now we start with A's first element, it is present in array B we save it in C[0], then go to second , now C is [0,1], and in next step we again have 1 to compare, which we have already compared.So for this situation we have to do check if element to be compare already exist in array C then we eliminate check for it.
(4) We store the found element in C (third array) and print it.
My full working code for it is :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
int[] aar1 = { 0, 1, 1, 7, 2, 6, 3, 9, 11, 2, 2,3,3,3,3,3,1 };
int[] aar2 = { 0, 1, 2, 3, 4, 5, 6, 11, 11, 1, 1, 1, 1 };
int[] arr3 = findIntersection(aar1, aar2);
Console.WriteLine("the array is : " + arr3);
Console.ReadKey();
}
private static int[] findIntersection(int[] aar1, int[] aar2)
{
int[] arr3 = { 0 };
if (aar1.Count() < aar2.Count())
{
int counter = 0;
arr3 = new int[aar1.Count()];
foreach (int var1 in aar1)
{
if (!checkifInThirdArray(var1, arr3))
{
foreach (int var2 in aar2)
{
if (var1 == var2)
{
arr3[counter++] = var1;
break;
}
}
}
}
}
else
{
int counter = 0;
arr3 = new int[aar1.Count()];
foreach (int var2 in aar2)
{
if (!checkifInThirdArray(var2, arr3))
{
foreach (int var1 in aar1)
{
if (var2 == var1)
{
arr3[counter++] = var2;
break;
}
}
}
}
}
return arr3;
}
private static bool checkifInThirdArray(int var1, int[] arr3)
{
bool flag = false;
if (arr3 != null)
{
foreach (int arr in arr3)
{
if (arr == var1) { flag = true; break; }
}
}
return flag;
}
}
}
One space complexity issue i found is (the others i would really appreciate if you let me know with solution if you find any) :
(1) When i allocate the size to third array, i allocate the Min of the two arrays to be compared, In case if the intersection element are too less then we
have unnecessarily allocated the extra memory. How to solve this issue ?
Please note that i don't have to use any inbuilt function like intersection() or any other.
It sounds like your solution is an O(n2) one in that, for every single element in one array, you may need to process every single element in the other (in the case where the intersection is the null set). You should be aware that C# actually has facilities for finding the intersection of arrays but, should you wish to implement your own, read on.
You would probably be better of sorting both arrays (in-place if allowed otherwise to a separate collection) then doing a merge-check of the two to construct another. The sort could be O(n log n) and the merge check would be O(n).
If you're wondering what I mean by merge check, it's simply processing both (sorted) arrays side by side.
If the first element in both matches, you have an intersect point and you should store that value and advance both lists until the next value is different.
If they're different, there's no intersect point and you can advance the array with the lowest value until it changes.
By way of example, here's some code in Python (the ideal pseudo-code language) that implements such a solution. Array a contains all the multiples of three between 0 and 18 inclusive (in arbitrary order and including duplicates), while array b has all the even numbers in that range (again, with some duplicates and ordered "randomly").
a = [0,3,15,3,9,6,12,15,18,6]
b = [10,0,2,12,4,6,18,8,16,10,12,6,14,16]
# Copy and sort.
a2 = a; a2.sort()
b2 = b; b2.sort()
# Initial pointers and results for merge check.
ap = 0
bp = 0
c = []
# Continue until either array is exhausted.
while ap < len(a2) and bp < len(b2):
# Check for intersect or which list has lowest value.
if a2[ap] == b2[bp]:
# Intersect, save, advance both lists to next number.
val = a2[ap]
c.append(val)
while ap < len(a2) and a2[ap] == val:
ap += 1
while bp < len(b2) and b2[bp] == val:
bp += 1
elif a2[ap] < b2[bp]:
# A has smallest, advance it to next number.
val = a2[ap]
while ap < len(a2) and a2[ap] == val:
ap += 1
else:
# B has smallest, advance it to next number.
val = b2[bp]
while bp < len(b2) and b2[bp] == val:
bp += 1
print(c)
If you run that, you'll see the intersect list that's formed between the two arrays:
[0, 6, 12, 18]
Maybe I am not understanding you right but why don't you use the following;
int[] aar1 = { 0, 1, 1, 7, 2, 6, 3, 9, 11, 2, 2,3,3,3,3,3,1 };
int[] aar2 = { 0, 1, 2, 3, 4, 5, 6, 11, 11, 1, 1, 1, 1 };
aarResult = aar1.Intersect(aar2).ToArray();
This will result in an array with only the space needed and intersects the arrays. You can also initialize the aarResult as follows to get the minimum array size:
int[] aarResult = new int[Math.Min(aar1.Count(), aar2.Count())];
You can use LINQ Intersect method. It uses hashing and works for linear O(N+M) which is faster than your algorithm:
int[] aar1 = { 0, 1, 1, 7, 2, 6, 3, 9, 11, 2, 2, 3, 3, 3, 3, 3, 1 };
int[] aar2 = { 0, 1, 2, 3, 4, 5, 6, 11, 11, 1, 1, 1, 1 };
int[] result = aar1.Intersect(aar2).ToArray();
It will also solve your unnecessarily allocated items problem, because it will create an array of the exact answer size.
In C# I have three arrays, string[] array1, 2 and 3 and they all have differnt values. I would love to do what I can do in php which is:
$array = array();
$array[] .= 'some value';
Whats the equivalent way of doing this in C#?
In C#, you'd typically use a List<string> instead of string[].
This will allow you to write list.Add("some value") and will "grow" the list dynamically.
Note that it's easy to convert between a list and an array if needed. List<T> has a constructor that takes any IEnumerable<T>, including an array, so you can make a list from an array via:
var list = new List<string>(stringArray);
You can convert a list to an array via:
var array = list.ToArray();
This is only required if you need an array, however (such as working with a third party API). If you know you're going to work with collections that vary in size, it's often better to just always stick to List<T> and not use arrays.
You can create a list and add the array values to it and then convert that list back to array.
int[] array1 = { 1, 2, 3, 4, 5 };
int[] array2 = { 6, 7, 8, 9, 10 };
// Create new List of integers and call AddRange twice
var list = new List<int>();
list.AddRange(array1);
list.AddRange(array2);
// Call ToArray to convert List to array
int[] array3 = list.ToArray();
You could use dinamic lists List<string>. You can do
List<string> TotalList = array1.ToList();
Then you can TotalList.AddRange(array2) and so on....
List<T> or LINQ may be the easiest solutions, but you can also do it the old fashioned way:
// b1 is now 5 bytes
byte[] b1 = Get5BytesFromSomewhere();
// creating a 6-byte array
byte[] temp = new byte[6];
// copying bytes 0-4 from b1 to temp
Array.copy(b1, 0, temp, 0, 5);
// adding a 6th byte
temp[5] = (byte)11;
// reassigning that temp array back to the b1 variable
b1 = temp;
if you simply want to merge your arrays
use linq .Concat
array1 = array1.Concat(array2).Concat(array3).ToArray();
Easy with linq:
int[] array1 = { 1, 2, 3, 4, 5 };
int[] array2 = { 6, 7, 8, 9, 10 };
int[] array3 = { 3, 4 ,5, 9, 10 };
var result = array1
.Concat(array2)
.Concat(array3)
.ToArray();