0
\$\begingroup\$

I'd like to get the indices of elements of an array with particular element. Is it okay or, or how can I make it even better?

//string Input = "Net Sales,COGS";

int[] numbers = { 0, 1, 2, 3, 4, 5 };
string[] Values = { "Net Sales", "COGS", "COGS%", "Gross Profit", "GP%", "Quantity" };

string[] selectedValues = Input.Split(new char[] { ',' });
selectedIndex = new int[selectedValues.Length];
selectedIndex = selectedValues.Select(n => Array.IndexOf(Values, n)).ToArray();

for (int i = 0; i < selectedIndex.Length; i++)
    numbers = numbers.Where(val => val != selectedIndex[i]).ToArray();

selectedIndex = numbers;
\$\endgroup\$

1 Answer 1

5
\$\begingroup\$

First of all your code doesn't compile.

Second, your code doesn't do what you state - "Remove particular element from an array".

Third, what exactly do you mean by "Remove"? You want to set these elements to null or compact your array? In second case what do you need indexes of other elements for (their indexes will change when you compact your array)?

Ok, now lets start with a declaration of a contract:

You want to get a multivalue result: filtered array and indexes of remaining elements.

public struct Result
{
    public readonly string[] FilteredArray;
    public readonly List<int> IndexesOfRemainingElements;

    public Result(string[] filteredArray, List<int> indexesOfRemainingElements)
    {
        FilteredArray = filteredArray;
        IndexesOfRemainingElements = indexesOfRemainingElements;
    }
}

Now, I'd rewrite your method in this way:

static Result FilterArray(string[] array, string[] input)
{
    var remainingElements = array.Where(i => !input.Contains(i)).ToArray();

    return new Result(remainingElements, 
                      remainingElements.Select(i => Array.IndexOf(array, i)).ToList());
}

And finally you can call it:

string input = "Net Sales,COGS";
string[] values = { "Net Sales", "COGS", "COGS%", "Gross Profit", "GP%", "Quantity" };

// Split has an override that accepts params char[]
var result = FilterArray(values, input.Split(','));    

Complete example here: https://dotnetfiddle.net/4wbfpC

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Semantically it would be clearer to use Except to calculate the remainingElements: var remainingElements = array.Except(input).ToArray() \$\endgroup\$
    – ChrisWue
    Mar 10, 2015 at 8:33
  • 1
    \$\begingroup\$ @ChrisWue, I usually try to be exceptionally cautious with set-based methods like Except because they also apply Distinct (stackoverflow.com/questions/2975944/…). \$\endgroup\$
    – aush
    Mar 10, 2015 at 8:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.