I have a string array in C# like so:
string[] sites = new string[] {
"http://foobar.com",
"http://asdaff.com",
"http://etc.com"
};
I'm using this array in a foreach and I would like to be able to add a "type" value of 1, 2, or 3, depending on which site I am currently iterating through. I am concatenating data with the StringBuilder from these sites. Now, I could store the site as a varchar, but it would be really neat, since this array will NEVER change to associate a number with the string and build it that way.
Use for loop instead of foreach:
for(int i = 0; i < sites.Length; i++)
{
// use sites[i]
}
LINQ's Select can be used to project an index onto a collection.
sites.Select((x, n) => new { Site = x, Index = n })
You can use a dictionary for this - Dictionary<int, string> (or Dictionary<string, int>).
var sitesWithId = new Dictionary<string, int>
{
new { "http://foobar.com", 1},
new { "http://asdaff.com", 2},
new { "http://etc.com", 3}
}
Another option is to just use a List<string> and IndexOf to find out the index.
var sites = new List<string> {
"http://foobar.com",
"http://asdaff.com",
"http://etc.com"
};
var foobarIndex = sites.IndexOf("http://foobar.com");
A third option, using the static IndexOf methods of Array and not changing your array at all:
var foobarIndex = Array.IndexOf(sites, "http://foobar.com");
Try with for loop;
for(int i = 0; i < sites.Length; i++)
{
Console.WriteLine(sites[i]);
}
using for elements of sites[] array like this;
sites[1]
sites[2]
sites[3]
or you can use Dictionary<TKey, TValue> as Oded suggest.
Related
I have a class that has a bunch of different variables and a couple lists 1 in particular holds ints(positionInts)
I also have a list(teamsList) for holding objects I have created from that class
now I would like to sort the team's list by positions values
Hopefully, I'm not being too vague as the project I'm working on is full of not well-written code so it can be hard to explain.
This function orders the list according to your precondition.
private List<String> OrderList(List<String> teams, int[] positions)
{
List<String> orderedTeams;
Dictionary<int, string> teamsToOrder = new Dictionary<int, string>();
int position = 0;
foreach (string team in teams)
{
teamsToOrder.Add(positions[position], teams[position]);
position = position + 1;
}
orderedTeams = teamsToOrder.OrderByDescending(team => team.Key).Select(team => team.Value).ToList();
return orderedTeams;
}
If I understand your question correctly, then you have list of arbitrary type, for example list of strings:
var teamsList = new List<String> { "team1", "team2", "team3", "team4" };
Next up, you have enumeration of integers:
var positionInts = new[] { 2, 3, 1, 0 };
And your goal is to order teamsList based on sequence numbers of the positionInts. In that case you can use following method:
static IEnumerable<T> OrderBySequence<T>(IEnumerable<T> source, IEnumerable<Int32> sequence)
{
for (var i = 0; i < Math.Min(source.Count(), sequence.Count()); i++)
{
var s = sequence.ElementAt(i);
if (s > -1 && s < source.Count())
{
yield return source.ElementAt(s);
}
}
}
Which will produce:
team3
team4
team2
team1
I have this code snippet as below which iterates over a split string.
if (!string.IsNullOrEmpty(profile.ContactNumber))
{
var splitContract = profile.ContactNumber.Split(new string[] { "and", "&" }, StringSplitOptions.RemoveEmptyEntries);
foreach (var contract in splitContract)
{
//check the split if it contains "x" or "X" character - if it does contain, it means it's a valid contract
if (contract.Contains("x") || contract.Contains("X"))
{
var condensedString = contract.Replace(" ", "");
var split = condensedString.Split(new char[] { 'x', 'X' });
GetNumbersOnly(split);
}
}
}
private void GetNumbersOnly(string[] inputArray)
{
var ListKeyValuePair = new List<KeyValuePair<string, string>>();
foreach (var item in inputArray)
{
var numberToAdd = Regex.Replace(item, "[^0-9]", "", RegexOptions.None);
ListKeyValuePair.Add(?, ?);
}
}
In GetNumbersOnly method, how can I populate List of KeyValuePair inside the for each loop?
The inputArray variable has an array element of [0] = 100, [1] = 5 for the first iteration and so on.
This is the desired output for the KeyValuePair {100, 5}, {200, 10}, {500, 15}.
Sorry, I can't seem to find any related scenario when I googled it. Any help with this is greatly appreciated.
Because the key and value are stored in separate array items, your logic is dependent on order. In cases like this, you should avoid for...each and instead use plain old for, which allows you to control the manner of iteration.
private void GetNumbersOnly(string[] inputArray)
{
var ListKeyValuePair = new List<KeyValuePair<string, string>>();
for (int i=0; i< inputArray.Length; i+=2) //The "2" here is very important!
{
var numberToAdd1 = Regex.Replace(inputArray[i], "[^0-9]", "", RegexOptions.None);
var numberToAdd2 = Regex.Replace(inputArray[i+1], "[^0-9]", "", RegexOptions.None);
ListKeyValuePair.Add(new KeyValuePair<string, string>(numberToAdd1, numberToAdd2));
}
}
The ListKeyValuePair.Add( ) function is expecting 1 field which is of type KeyValuePair. You need to make one of these with a new KeyValuePair() { key = item, value = numberToAdd };
Why are you keeping key value pairs in a list? Why not a Dictionary ? Do you want duplicate pairs?
I have a two dimensional array namely States. I create a one dimensional array, say SubState. Then I change SubState. I want to find new SubState in States and get the index. As an example:
int[][] States = new int[3][] { new int[] { 3, 3, 4 }, new int[] { 2, 5, 1 }, new int[] { 2, 3, 4 } };
int[] SubState = new int[States[0].Length];
States[0].CopyTo(SubState, 0);
SubState[0] -= 1;
I want to find the index of new SubState in State, which will be 2 in the example.
Thanks.
You're looking for SequenceEqual:
int index = -1;
for (int i = 0; i < States.Length; i++)
if (States[i].SequenceEqual(SubState))
{
index = i;
break;
}
If you define a LINQ FindIndex operator, you can express it more concisely using:
int index = States.FindIndex(s => s.SequenceEqual(SubState));
You can use SequenceEqual method inside a LINQ query, like this:
var nextStateIndex = States
.Select((a, i) => new {Index = i, Array = a})
.FirstOrDefault(p => p.Array.SequenceEqual(SubState))
?.Index;
if (nextStateIndex.HasValue) {
...
}
Note: this code uses the new ?. operator. If you are targeting C# version that does not have support for this operator, store FirstOrDefault result for an explicit null checking.
You can use Linq:
var index = -1;
var foundSubState = States.FirstOrDefault(x => {
index++;
return x.SequenceEqual(SubState);
});
var res = foundSubState != default(Array) ? index : -1;
i want to add new row to table but by passing both normal variables and array variable like the example below
int value1=1;
int value2=2;
int[] numbers = new int[] {3, 4, 5};
DataTable1.Rows.Add(value1,value2,numbers) // numbers as single items so the row will contain 5 values (1,2,3,4,5)
so should i build a new array and pass it ? or there a code spell to do that ?
thanks
This helper method will create a list from 1 to 5:
public IEnumerable<T> GetItemsAndCollectionsAsItems<T>(params object[] itemsAndCollections)
{
var result = new List<T>();
foreach (var itemOrCollection in itemsAndCollections)
{
var collection = itemOrCollection as IEnumerable<T>;
if (collection == null)
{
result.Add((T)itemOrCollection);
}
else
{
result.AddRange(collection);
}
}
return result;
}
And you call it this way:
int value1 = 1;
int value2 = 2;
int[] numbers = new int[] { 3, 4, 5 };
// Returns 1,2,3,4,5
IEnumerable<int> values = GetItemsAndCollectionsAsItems<int>(value1, value2, numbers);
Not sure to be happen with this Int Array but yah, have a look on this link, which stores data same as you want. Simply some tricky things have to do.
I have a list like
List<string> TempList = new List<string> { "[66,X,X]", "[67,X,2]", "[x,x,x]" };
I need to add data to the dictionary from the above list
Dictionary<int, int> Dict = new Dictionary<int, int>();
so the Dict should contain
Key --> 66 value --> 67
i need to take 66(first value) from first string([66,X,X]) and 67(first value) from second string( [67,X,X]) and add it as a key value pair into the dictionary.
Now i'm following string replacing and looping methodology to do this .
Is there any way to do this in LINQ or Regular expression.
After your comment that you're starting from a list of lists, I understood what you were after. I'm reusing Jaroslav's 'GetNumber' function here. Wrote my sample with array of array of string, but should work just the same. The code below will throw if you have duplicate keys, which I presume is what you want if you're using a dictionary.
var input = new []
{
new [] { "[66,X,X]", "[67,X,2]", "[x,x,x]" },
new [] { "[5,X,X]", "[8,X,2]", "[x,x,x]" }
};
var query = from l in input
select new
{
Key = GetNumber(l.ElementAt(0)),
Value = GetNumber(l.ElementAt(1))
};
var dictionary = query.ToDictionary(x => x.Key, x => x.Value);
Here is an example using both string.Split() and a Regex:
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
List<string> data = new List<string>() { "[66,X,X]", "[67,X,2]", "[x,x,x]" };
addToDict(data);
Console.ReadKey();
}
private static void addToDict(List<string> items)
{
string key = items[0].Split('[', ',')[1];
string val = items[1].Split('[', ',')[1];
string pattern = #"(?:^\[)(\d+)";
Match m = Regex.Match(items[0], pattern);
key = m.Groups[1].Value;
m = Regex.Match(items[1], pattern);
val = m.Groups[1].Value;
_dict.Add(key, val);
}
static Dictionary<string, string> _dict = new Dictionary<string, string>();
}
}
i suspect that your example is quite contrived though, so there may be a better solution especially if you need to process large numbers of strings into key/value pairs (i deliberately hardcoded index values because your example was quite simple and i didn't want to over complicate the answer). If the input data is consistent in format then you can make assumptions like using fixed indexes, but if there is a possibility of some variance then there may need to be more code to check the validity of it.
You can use a regular expression to extract the value from each item in the list, and if you want, use LINQ to select out two lists and zip them together (in C# 4.0):
var regex = new Regex(#"\d+");
var allValues = TempList.Select(x =>int.Parse(regex.Match(x).Value));
var dictKeys = allValues.Where((x,index)=> index % 2 == 0); //even-numbered
var dictValues = allValues.Where((x,index)=> index % 2 > 0); //odd numbered
var dict = dictKeys.Zip(dictValues, (key,value) => new{key,value})
.ToDictionary(x=>x.key,x=>x.value);
If you're using C# 3.5, you can use Eric Lippert's implementation of Zip().
IF I understand correctly: you want to create linked nodes like 66 -> 67, 67 -> 68, ... n -> n+1?
I would not use LINQ:
private static int GetNumber(string s)
{
int endPos = s.IndexOf(',');
return Int32.Parse(s.Substring(1, endPos-1));
}
And in code:
int first, second;
for (int i = 1; i < TempList.Count; i++)
{
first = GetNumber(TempList[i - 1]);
second = GetNumber(TempList[i]);
Dict.Add(first, second);
}
You should also perform checking, etc.
The sample assumes a list with at least 2 items.
List<List<string>> source = GetSource();
Dictionary<int, int> result = source.ToDictionary(
tempList => GetNumber(tempList[0]),
tempList => GetNumber(tempList[1])
);