Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Selecting elements from array according to indices specified in another array c#

Suppose we have an array with data:

double[] x = new double[N] {x_1, ..., x_N};

And array of size N containing labels corresponding to the elements of x:

int[] ind = new int[N] {i_1, ..., i_N};

What is the fastest way to select all elements from x that have certain label I according to ind?

For example,

x = {3, 2, 6, 2, 5}
ind = {1, 2, 1, 1, 2}
I = ind[0] = 1

Result:

y = {3, 6, 2}

Clearly, it can be easily (but not efficiently and clean) done with loops, but I think there should be the way how to do that using .Where and lambdas..Thanks

EDIT:

The answer provided by MarcinJuraszek is completely correct, thanks. However, I've simplified the question in hope that it would work in my original situation. Could you please take a look what is the problem if we have generic types:

T1[] xn = new T1[N] {x_1, ..., x_N};
T2[] ind = new T2[N] {i_1, ..., i_N};
T2 I = ind[0]

Using the solution provided I get an error "Delegate 'System.Func' does not take 2 arguments":

T1[] y = xn.Where((x, idx) => ind[idx] == I).ToArray();

Thank you very much

like image 675
Oleg Shirokikh Avatar asked Apr 03 '13 19:04

Oleg Shirokikh


People also ask

Can you access an array element by referring to the index?

Access Array ElementsYou can access an array element by referring to its index number. The indexes in NumPy arrays start with 0, meaning that the first element has index 0, and the second has index 1 etc.

Can an array be assigned to another array in C?

There are two ways to copy an array: using an assignment statement. When assigning the values of one array to another array, the two arrays must have the same size. using the COPYARRAY function.

How do you select an index in an array?

To specify the indexes, enter a value in the Input array indexes field of the Cardinality properties page for the transform. The indexes are 1-based, which means that the first element of the array is referenced as 1, the second element as 2, and so on.


1 Answers

How about that:

var xs = new[] { 3, 2, 6, 2, 5 };
var ind = new[] { 1, 2, 1, 1, 2 };
var I = 1;

var results = xs.Where((x, idx) => ind[idx] == I).ToArray();

It uses second, less popular, Where overload:

Enumerable.Where<TSource>(IEnumerable<TSource>, Func<TSource, Int32, Boolean>)

which has item index available as predicate parameter (called idx in my solution).

Generic version

public static T1[] WhereCorresponding<T1, T2>(T1[] xs, T2[] ind) where T2 : IEquatable<T2>
{
    T2 I = ind[0];
    return xs.Where((x, idx) => ind[idx].Equals(I)).ToArray();
}

Usage

static void Main(string[] args)
{
    var xs = new[] { 3, 2, 6, 2, 5 };
    var ind = new[] { 1, 2, 1, 1, 2 };

    var results = WhereCorresponding(xs, ind);
}

Generic + double version

public static T[] Test<T>(T[] xs, double[] ind)
{
    double I = ind[0];

    return xs.Where((x, idx) => ind[idx] == I).ToArray();
}
like image 145
MarcinJuraszek Avatar answered Oct 08 '22 12:10

MarcinJuraszek