How to remove item from a simple array once? For example, a char array contains these letters:
a,b,d,a
I would like to remove the letter "a" one time, then the result would be:
a,b,d
Removing an item from an array is not really possible. The size of an array is immutable once allocated. There is no way to remove an element per say. You can overwrite / clear an element but the size of the array won't change.
If you want to actually remove an element and change the size of the collection then you should use List<char> instead of char[]. Then you can use the RemoveAt API
List<char> list = ...;
list.RemoveAt(3);
If your goal is to just skip the first 'a', then remove the second, you could use something like:
int first = Array.IndexOf(theArray, 'a');
if (first != -1)
{
int second = Array.IndexOf(theArray, 'a', first+1);
if (second != -1)
{
theArray = theArray.Take(second - 1).Concat(theArray.Skip(second+1)).ToArray();
}
}
If you just need to remove any of the 'a' characters (since you specified that the order is not relevant), you could use:
int index = Array.IndexOf(theArray, 'a');
if (index != -1)
{
theArray = theArray.Take(index - 1).Concat(theArray.Skip(index+1)).ToArray();
}
Note that these don't actually remove the item from the array - they create a new array with that element missing from the newly created array. Since arrays are not designed to change in total length once created, this is typically the best alternative.
If you will be doing this frequently, you may want to use a collection type that does allow simple removal of elements. Switching from an array to a List<char>, for example, makes removal far simpler, as List<T> supports simple APIs such as use List<T>.Remove directly.
You can use linq by trying the following
var someArray= new string[3];
someArray[0] = "a";
someArray[1] = "b";
someArray[2] = "c";
someArray= someArray.Where(sa => !sa.Equals("a")).ToArray();
Please note: This method is not removing the element from the array but that it is creating a new array that is excluding the element. This may have an effect on performance.
You might consider using a list or collection.
static void Main(string[] args)
{
char[] arr = "aababde".ToArray();
arr = RemoveCharacter(arr, 'a');
arr = RemoveCharacter(arr, 'b');
arr = RemoveCharacter(arr, 'd');
arr = RemoveCharacter(arr, 'z');
arr = RemoveCharacter(arr, 'a');
//result is 'a' 'b' 'e'
}
static char[] RemoveCharacter(char[] array, char c)
{
List<char> list = array.ToList();
list.Remove(c);
return list.ToArray();
}
Related
I have an array :
string[] arr = new string[2]
arr[0] = "a=01"
arr[1] = "b=02"
How can I take those number out and make a new array to store them? What I am expecting is :
int [] newArr = new int[2]
Inside newArr, there are 2 elements, one is '01' and the other one is '02' which both from arr.
Another way besides Substring to get the desired result is to use String.Split on the = character. This is assuming the string will always have the format of letters and numbers, separated by a =, with no other = characters in the input string.
for (var i = 0; i < arr.Length; i++)
{
// Split the array item on the `=` character.
// This results in an array of two items ("a" and "01" for the first item)
var tmp = arr[i].Split('=');
// If there are fewer than 2 items in the array, there was not a =
// character to split on, so continue to the next item.
if (tmp.Length < 2)
{
continue;
}
// Try to parse the second item in the tmp array (which is the number
// in the provided example input) as an Int32.
int num;
if (Int32.TryParse(tmp[1], out num))
{
// If the parse is succesful, assign the int to the corresponding
// index of the new array.
newArr[i] = num;
}
}
This can be shortened in a lambda expression like the other answer like so:
var newArr = arr.Select(x => Int32.Parse(x.Split('=')[1])).ToArray();
Though doing it with Int32.Parse can result in an exception if the provided string is not an integer. This also assumes that there is a = character, with only numbers to the right of it.
Take a substring and then parse as int.
var newArr = arr.Select(x=>Int32.Parse(x.Substring(2))).ToArray();
As other answers have noted, it's quite compact to use linq. PM100 wrote:
var newArr = arr.Select(x=>Int32.Parse(x.Substring(2))).ToArray();
You asked what x was.. that linq statement there is conceptually the equivalent of something like:
List<int> nums = new List<int>();
foreach(string x in arr)
nums.Add(Int32.Parse(x.Substring(2);
var newArr = nums.ToArray();
It's not exactly the same, internally linq probably doesn't use a List, but it embodies the same concept - for each element (called x) in the string array, cut the start off it, parse the result as an int, add it to a collection, convert the collection to an array
Sometimes I think linq is overused; here probably efficiencies could be gained by directly declaring an int array the size of the string one and filling it directly, rather than adding to a List or other collection, that is later turned into an int array. Proponents of either style could easily be found; linq is compact and makes relatively trivial work of more long hand constructs such as loops within loops within loops. Though not necessarily easy to work out for those unfamiliar with how to read it it does bring a certain self documenting aspect to code because it uses English words like Any, Where, Distinct and these more quickly convey a concept than does looking at a loop code that exits early when a test returns true (Any) or builds a dictionary/hashset from all elements and returns it (Distinct)
I has a multidimentional string array as below
string[][] data = new string[3][];
the item in the string array as below
data[0]
[0] "EUG5" string
[1] "FA1" string
data[1]
[0] "9.000000" string
[1] "1000" string
data[2]
[0] "1" string
[1] "0" string
I wish to remove the data[0][1], data[1][1] and data[2][1], this is base on the condition on data[2] where it is "0". Is it possible to do this?
You can use Array.Resize to do what you want to do. Try this LINQpad script:
var data = new string[][]{new []{"EUG5","FA1"},new []{"9.000000","1000"},new []{"1","0"}};
data.Dump();
Array.Resize(ref data[0],1);
Array.Resize(ref data[1],1);
Array.Resize(ref data[2],1);
data.Dump();
It produces this:
You can also use Array.Copy to move elements around, so this is the more generic case:
var data = new string[][]{new []{"EUG5","FA1"},new []{"9.000000","1000"},new []{"1","0"}};
data.Dump();
var colToDelete = 0;
for (int i = 0; i < data.Length; i++)
{
Array.Copy(data[i],colToDelete+1,data[i],colToDelete,data[i].Length-colToDelete-1);
Array.Resize(ref data[i],data[i].Length-1);
}
data.Dump();
but like the other posters correctly state, it's way easier with a List.
You cannot remove elements from an Array object in C#, all Arrays are immutable. To get the flexibility you are looking for you want to use the List object.
If for some reason you are stuck and have to use arrays, then you could make a method that accepts an Array and Returns an Array. Then you could remove the objects like this:
public string[][] RemoveElement(string[][] array, int coordinateA, int coordinateB)
{
var ListOfItems = new List<List<string>>();
foreach(string[] item in array)
ListOfItems.add(new List<string>(item));
ListOfItems[coordinateA].RemoveAt(coordinateB);
var ReturnArray = new string[ListOfItems.Length][]();
for(int i = 0; i < ListOfItems.Length; i++)
ReturnArray[i] = ListOfItems[i].ToArray();
return ReturnArray;
}
Of couse this is not a very optimized solution, but it will get the job done. There probably are extension method solutions for removing elements from arrays, but it would be far better to just use List object, and then return an array at the end of your code by calling List.ToArray() if it is necessary.
If you don't mind in creating new Array of Arrays instead of reusing existing array you could do this.
data = data
.Select(x=> data[2][1] == "0"? // Condition to filter
x.Take(1).ToArray()
: x.ToArray())
.ToArray();
Check this Demo
When I try to copy arrays into a jagged array. My goal is to take an array of type char, separate the "words" into separate arrays (I use an already working function for it) and want to put them into an array.
static char[][] split_string(char[] str)
{
int length = count_words(str);
char[][] sentence = new char[length][];
int start = 0;
int end = 0;
int word = 0;
int i = -1;
while (i != str.Length)
{
i++;
if (str[i]==' ')
{
end = i-1;
char[] aux_array = substring(str, start, end);
//issue
aux_array.CopyTo(sentence[word], 0);
//alternative (not working either)
/*
for(int j=0; j<aux_array.Length;j++)
{
sentence[word][j] = aux_array[j];
}
*/
while (str[i]==' ')
{
i++;
}
word++;
start = i;
}
}
return sentence;
}
For information,
substring if of the form: substring(array, int, int) -> array
count_word is of the form: count_word(array) -> int
My goal is to take an array of type char, separate the "words" into separate arrays (I use an already working function for it) and want to put them into an array.
Then just put them into array
//...
sentence[word] = substring(str, start, end);
Note that the jagged array elements are null by default and you didn't allocate them, so you probably are getting null reference exception. If you really need to do a copy of the returned array, then the easiest way is to use Array.Clone method like this
sentence[word] = (char[])substring(str, start, end).Clone();
It is easier to work with strings and not raw char arrays but I assume it is with intention that you have decided to use char arrays.
One way to simplify your code is to build the char array as you go instead of preallocating it. .NET arrays have fixed size but List<T> allows you to grow a collection of items.
You can also change your function into an iterator block to simplify it further. When a word is complete you yield return it to the caller.
IEnumerable<char[]> SplitString(char[] str) {
var word = new List<char>();
foreach (var ch in str) {
if (ch == ' ') {
if (word.Count > 0) {
yield return word.ToArray();
word = new List<char>();
}
}
else
word.Add(ch);
}
if (word.Count > 0)
yield return word.ToArray();
}
This function will not return an array so if you want an array of arrays (jagged array) you need to use ToArray():
var str = "The quick brown fox jumps over the lazy dog".ToCharArray();
var result = SplitString(str).ToArray();
This code will correctly handle multiple spaces and spaces in the beginning and end of the source string.
string[] SalesReferenceArray = {};
int i=0;
if (chk_Select.Checked == true)
{
SalesReferenceArray[i] = Convert.ToString((Label)grdSales.FindControl("lblSalesReference"));
i++;
}
Index was outside the bounds of the array while assigning label to array
string[] SalesReferenceArray = {};
Your array is empty, i.e. it does not have any items. Trying to access first item (i.e. item at index 0) gives you IndexOutOfRange error, because index of item should be non-negative and less than array length.
If you need to have only one item, then you don't need array at all. Just declare variable of string type:
string SalesReference;
If you want to add/remove items dynamically then use list instead of array:
List<string> SalesReferences = new List<string>();
if (chk_Select.Checked) // don't compare with true
{
string reference = Convert.ToString((Label)grdSales.FindControl("lblSalesReference"));
SalesReferences.Add(reference);
}
NOTE: I think you need to use Label.Text instead of trying to convert label to string.
You are creating an empty array with 0 size, i.e. you are using the short-hand assignment syntax and not specifying any elements.
You will need to fix your code by changing it to specify a size, like so:
string[] SalesReferenceArray = new string[10]; // creates an array with 10 empty elements
If you don't know the size of your array in advance, you might want to use a List instead:
List<string> salesReferenceList = new List<string>();
if (chk_Select.Checked == true)
{
salesReferenceList.Add(Convert.ToString((Label)grdSales.FindControl("lblSalesReference")));
}
A list would be more appropriate for you as it's dynamic.
List<string> SalesReferences = new List<string>();
then add to it like...
SalesReferences.Add("Hello World");
So I'm trying to fill a char array with user input. However I do not want to specify the length of the array myself, thus limiting the user to the amount they can input. For example my code below will only allow the user to enter 5 characters and then will exit. Code in any language would be fine. (The below is C#).
Console.Write("Enter a number of characters of your choice...click 1 to exit: ");
bool exitCondition;
int counter = 0;
char[] character = new char[5];
do
{
exitCondition = false;
try
{
character[counter] = char.Parse(Console.ReadLine());
if (character[counter] == '1')
exitCondition = true;
}
catch (Exception ex)
{
Console.WriteLine("Error: {0}", ex.Message);
}
counter++;
}
while (exitCondition == false && counter < 5);
You need to use a collection, which allows the collection of elements to grow or shrink. In Java an ArrayList would be appropriate for your scenario. In C# you would most likely use a List.
C#
List<char> list = new List<char>();
list.Add('a');
list.Add('b');
Java
List<Character> list = new ArrayList<Character>();
list.add('a');
Array's are static in size. Use java.util.ArrayList ( from Collection framework) which is resizable-array.
List<Character> chars = new ArrayList<Character>();
chars.add('a');
chars.add('c');
chars.add('d');
Resizable-array implementation of the List interface. Implements all optional list operations, and permits all elements, including null. In addition to implementing the List interface, this class provides methods to manipulate the size of the array that is used internally to store the list.
Ref
StringBuilder is all you need
StringBuidler sb = new StringBuilder();
sb.append(c);
...
then you can get char array from it if you really want it
char[] a = sb.toString().toCharArray();
though typically it is just converted into a String
String s = sb.toString()
there is also a method to work with StringBuilder internal char[] directly
char c = sb.charAt(i)
Alternatively if you really want to use only array for some hidden reason :), then you can ask user for number of input items and initialize array accordingly.
Thanks,
Naval