I have 2 arrays;
a[ ] = (1,3,4)
b[ ] = (2,4,5)
How would i compare the above 2 arrays(lists actually) to find “4” exists in both of them?
I have 2 arrays;
a[ ] = (1,3,4)
b[ ] = (2,4,5)
How would i compare the above 2 arrays(lists actually) to find “4” exists in both of them?
If you look at List.Contains reference, you can add a new method that checks for a number similar to how Equal works in the example.
That or go through each and do it manually.
Thanks, i just found out about the .Contains, and it does the job.
Somehow its slow though.
And now i have a different problem.
a[ ] = (1,3,2)
d[ ] = [20,10,30]
When i sort the d[ ] to 10, 20, 30, i would like a[ ] to be sorted to 3, 1, 2
How can i do that?
Or, how can i get the index value of if .Contains true?
i mean, if .Contains would return an index value, it would be another easy solution for my case.
EDIT: Okay, found it. .OrderBy does just what i want.
Thanks for any help.
Well, i just cant make this work.
I have 2 array lists as follows, length of arrays is equal:
a[ ] = (transform1, transform2…etc)
b[ ] = (float1, float2…etc)
After sorting b[ ] into descending or ascending order, How do i sort a[ ] according to b[ ] ?
If you have two arrays this closely tied, it usually means that their contents are closely tied. When two types of data are closely tied, it’s best to combine them in a single class or struct, for example (just making up the naming here, as i don’t know what the floats and transforms actually represent):
struct TransformDistance
{
public float distance;
public Transform transform;
}
You can then use a single TransformDistance[ ] and sort it with System.Array.Sort and a custom IComparer class to make it sort by distance:
That means re-writing the whole code here. Isnt there any magic c# code to Sort(a[ ], with b[ ]) something?
This vary useful form of the System.Array.Sort function sorts two arrays simultaneously. It sorts both arrays but bases the ordering on the keys in the first array.
Wonderful, however i am using lists as they are expandable, and passing lists into arrays back and forth is a concern for speed.
Isnt there such a sort command for lists?
using System.Linq;
//…
//Where “someObject” is the object you are calculating distances to, and where “transforms” is your array or list of Transforms.
//If you need the distances and the Transforms:
var transdist = transforms.Select(item => new { transform = item, distance = Vector3.Distance(item.position, someObject.position) }).OrderBy(td => td.distance);
//then you could do
float[ ] distanceArray = transdist.Select(td=>td.distance).ToArray();
//or
List distanceList = transdist.Select(td=>td.distance).ToList();
//and
Transform[ ] transformArray = transdist.Select(td=>td.transform).ToArray();
//or
List transformList = transdist.Select(td=>td.transform).ToList();
//If you just need the order of the Transforms
transforms = transforms.OrderBy(t=>Vector3.Distance(t.position, someObject.position)).ToArray(); //or “ToList()”
Thanks for the tip Antitheory, still yours convert to Arrays back and forth. Anyways i did it as follows and using arrays now.
sortedTransforms = transforms.ToArray();
sortedDistances = distances.ToArray();
Array.Sort(sortedDistances , sortedTransforms );
So, it sorts my transforms according to distances in ascending order.
Now i have worse problems though, i need a priorityqueue and i converted a c++ example i found on google into following:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public interface IPriorityQueue<T> {
int PQ_Push (T i);
T PQ_Pop ();
T PQ_Peek ();
void PQ_Update (int i);
}
public class PriorityQueue<T> : IPriorityQueue<T> {
protected List<T> InnerList = new List<T>();
protected IComparer<T> mComparer;
//Constructors
public PriorityQueue() {
mComparer = Comparer<T>.Default;
}
public PriorityQueue(IComparer<T> comparer) {
mComparer = comparer;
}
public PriorityQueue(IComparer<T> comparer, int capacity) {
mComparer = comparer;
InnerList.Capacity = capacity;
}
//Methods
protected void SwitchElements(int i, int j) {
T h = InnerList[i];
InnerList[i] = InnerList[j];
InnerList[j] = h;
}
protected virtual int OnCompare(int i, int j) {
return mComparer.Compare(InnerList[i], InnerList[j]);
}
public void Clear() {
InnerList.Clear();
}
public int Count {
get{ return InnerList.Count; }
}
public void RemoveLocation(T item) {
int index = -1;
for(int i=0; i<InnerList.Count; i++) {
if (mComparer.Compare(InnerList[i], item) == 0)
index = i;
}
if (index != -1)
InnerList.RemoveAt(index);
}
public T this[int index] {
get { return InnerList[index]; }
set {
InnerList[index] = value;
PQ_Update(index);
}
}
// Push an object onto the PQ
//Returns the index in the list where the object is _now_. This will change when objects are taken from or put onto the PQ.
public int PQ_Push(T i) {
int p = InnerList.Count,p2;
InnerList.Add(i);
do
{
if(p==0)
break;
p2 = (p-1)/2;
if(OnCompare(p,p2)<0)
{
SwitchElements(p,p2);
p = p2;
}
else
break;
}while(true);
return p;
}
// Get the smallest object and remove it.
// Returns the smallest object.
public T PQ_Pop() {
T result = InnerList[0];
int p = 0,p1,p2,pn;
InnerList[0] = InnerList[InnerList.Count-1];
InnerList.RemoveAt(InnerList.Count-1);
do
{
pn = p;
p1 = 2*p+1;
p2 = 2*p+2;
if(InnerList.Count>p1 OnCompare(p,p1)>0)
p = p1;
if(InnerList.Count>p2 OnCompare(p,p2)>0)
p = p2;
if(p==pn)
break;
SwitchElements(p, pn);
}while(true);
return result;
}
// Notify the PQ that the object at position i has changed
// and the PQ needs to restore order.
// Since you dont have access to any indexes (except by using the
// explicit IList.this) you should not call this function without knowing exactly
// what you do.
public void PQ_Update(int i)
{
int p = i,pn;
int p1,p2;
do
{
if(p==0)
break;
p2 = (p-1)/2;
if(OnCompare(p,p2)<0)
{
SwitchElements(p,p2);
p = p2;
}
else
break;
}while(true);
if(p<i)
return;
do
{
pn = p;
p1 = 2*p+1;
p2 = 2*p+2;
if(InnerList.Count>p1 OnCompare(p,p1)>0)
p = p1;
if(InnerList.Count>p2 OnCompare(p,p2)>0)
p = p2;
if(p==pn)
break;
SwitchElements(p,pn);
}while(true);
}
// Get the smallest object without removing it.
// Returns the smallest object
public T PQ_Peek() {
if(InnerList.Count>0)
return InnerList[0];
return default(T);
}
}
So far it works, but occasionally i get outof range error. Can you see why?
Actually it doesn’t if you use “ToList” instead of “ToArray”. I just included the ToArray examples to show you that it was possible to have them in arrays if you wanted/needed them in arrays.
Instead of a PriorityQueue class, why not just use a regular list and order it after adding an entry?
Okay ive re-written the whole thing and im stuck with this sorting again.
class Enemy {
id;
}
class Entity {
List rivals = new List();
List distances = new List();
}
class mainclass : mono {
.
.etc
function {
.
.etc
rivals = getVisibleEnemyList();
distances = getVisibleEnemyDistanceList();
Currently the above lists have same Length and has same indexes
But for the sake of my purpose,
How do i sort distances from shortest to longest here in ascending order as well as the rivals.id here according to sorted distances at the same time
}
}
For your first problem you should be able to use the Intersect extension (i.e. using System.Linq) if you convert them to List<>: a.Intersect(b) will create an IEnumerable with all the common elements of the two arrays.
As to your second question, this may help: Order an Array like another Array in C# - Stack Overflow
This was the solution I thought of and google came through with someone already having written the code. You just create a sort predicate that records the ordering, then apply the ordering to the other array.
I just cant write this thing with my own Comparer which i would really wanted to learn.
Anyways, rather than messing with lists sorting, i now do the whole thing with a lookup dictionary which according to some resources is much faster.
Thanks for any help.
Yeah I just thought of the Dictionary as well (because you obviously have unique Rivals in your one list, you can use that as the key).
Custom comparers are not that difficult to learn and it can be worth it.
For example I created a comparer to compare sort Vector3’s by x,y,z (for a fast lookup).
public static int ComparePoints(Vector3 v1, Vector3 v2)
{
if (v1.x != v2.x)
{
return v1.x.CompareTo(v2.x);
}
if (v1.y != v2.y)
{
return v1.y.CompareTo(v2.y);
}
return v1.z.CompareTo(v2.z);
}
Vector3[ ] points;
//…
Array.Sort(points, ComparePoints);
There are other ways of doing it, by implementing the IComparable interface for example. I found this method fairly simple.
It is obviously easy to customCompare smiliar objects, but how would i compare completely different objects which has some or atleast 1 identical parts?
Can you show me a smiliar comparer for a Vector3 and a Transform? (obviously Transform has position to compare with) Or in my case the rivals indexes with distances indexes?