I am writing a program where I need to swap values from nested list.
Here is what I am looking for example:
Let's say I have a List<object[]> where these list contains two rows as below:
{"id1", "id2", "id3"}, {1,2,3}
Now I want to make it like below:
{"id1", 1}, {"id2", 2}, {"id3", 3}
How can I do that in C#?
Hopefully I have cleared my point.
With 2 input sequences, this can be treated as a "zip" operation:
List<object[]> list = new List<object[]>
{
new object[] {"id1", "id2", "id3" },
new object[] {1,2,3},
};
var rotated = Enumerable.Zip(list[0], list[1],
(x, y) => new object[] { x, y }).ToList();
Note I would advise against using lots of object[] etc here. There's almost always a better way to represent the data.
With an arbitrary number of input sequences, this would need to be done as a "transpose" operation.
Related
In C#, I can have a Hashtable that accepts different data types for the values. But I want a datastructure that can maintain the insertion order.
I am coming to C# from Java background and I would like to know a clean way of solving it. I don't want the O(1) lookup complexity of an Hashtable.
Here is how my Hashtable would be.
public void foo() {
List<string> mylist1 = new List<string>(new string[] { "1", "2", "3" });
List<int> mylist2 = new List<int>(new int[] { 1, 2, 3 });
Hashtable hashTable = new Hashtable();
hashTable.Add("1", "One");
hashTable.Add("2", 2);
hashTable.Add("3", mylist1);
hashTable.Add("4", mylist2);
foreach(string key in hashTable.Keys)
{
Console.WriteLine(String.Format("{0}: {1}", key, hashTable[key]));
}
}
If I want to maintain the insertion order, List seems to be the right data structure. I am thinking of new List<Tuple<string, var>>. But my values can be of any data type.
So I am looking for a data structure that can maintain insertion order and allow different datatypes for the values (like an Hashtable). How can I achieve this in C#?
Should I use a dictionary data structure that preserves the order instead?
First list:
a=[0,1,2,3,4]
Second list:
b=[4.233,5.2324,6.342,3.233,8.435]
Is there any way to merge these two lists into a json object?
Ex: object: [{"a":0,"b":4.233},{"a":1,"b":5.2324},{"a":2,"b":6.342},{"a":3,"b":3.233},{"a":4,"b":8.435}]
Assuming you're working server side and have two arrays a and b,
var a = new[] {0, 1, 2, 3, 4};
var b = new[] {4.233, 5.2324, 6.342, 3.233, 8.435};
var c = a.Zip(b, (ai, bi) => new{a = ai, b = bi});
At this point, JsonConvert.SerializeObject(c) will output the example JSON you provided. You will need JSON.Net.
Zip() takes the nth element of both lists, and allows you to apply a function to each combination.
Is there a simple lambda expression to extract elements from one list and put them into another? without LINQ?
for example to map, a source list of elements T to another list (or return a list) with the string name for each element in the source.
Update...with pseudocode.
List<int> intList = new List<int>() { 1, 2, 3};
List<string> stringList = new List<string>(intList.ToArray((i) => intList[i].ToString())); // this doesn't work obviously
stringList should be {"1", "2", "3"}
List<T>.ConvertAll() provides a straightforward way to change types without LINQ.
In your case...
List<string> stringList = intList.ConvertAll(i => i.ToString());
I'm looking for a way to get multiple keys with a single value. Yes, I've already used the search function, but most answers are for the opposite direction (multiple values per key), but I want the opposite.
The reasoning behind this is that I want keep multiple Item-IDs (it's for a Bot) per "main" ID, and throwing those multiple IDs into a value of the one is too slow to modify (looking for one value => looping trough all main IDs & getting each value, then checking if that ID exists).
Example
Key 1 => Value
Key 2 => Value
Key 3 => Value
Key 4 => Value
Key 5 => Value 2
Looking for Value should return: Key 1-4, not 5
So I'm looking for a way to do that easier - like I said above.
Anyone knows if that's possible and how to do it?
Thanks in advance.
Edit:
Looking at your edit, it really looks like you have designed this Dictionary backwards... your keys should be for matching values, not your values for matching keys.
You could do something like create a dictionary that maps outer-keys to inner-keys, then use the inner-key to index a second dictionary.
Example:
var outer = new Dictionary<int, Guid> {
{ 1, GuidA },
{ 2, GuidA },
{ 3, GuidA },
{ 4, GuidA },
{ 5, GuidB }
};
var inner = new Dictionary<Guid, Value> {
{ GuidA, Value1 },
{ GuidB, Value2 }
};
You would access it as: value = outer[inner[key]].
You may be overthinking your problem. Keys need to be unique in order to be useful for lookup operations. Values do not need to be unique. Multiple keys can point to the same value without causing problems.
Do the dictionary the other way around and make the value a list of items.
if for example Value is a string and Key 1-4 are ints your dictionary could look something like:
var theDictionary = new Dictionary<string, List<int>>();
retrieving Value by theDictionary["Value"] would then return a list of ints containing 1, 2, 3 and 4.
Edit - Added example:
var theDictionary = new Dictionary<string, List<string>>
{
{"Value", new List<string> {"Key 1", "Key 2", "Key 3", "Key 4", "Key 5",}},
{"Value2", new List<string> {"Key 5", "Key 2"}}
};
var oneToFour = theDictionary["Value"];
1) Servy is absolutely correct. If you're doing a search on anything but a key ... and if you're trying to retrieve anything but the corresponding value ... then something is definitely wrong. All things being equal, you probably DON'T want a dictionary.
2) Based on what you're saying, perhaps a better collection type might be a List. Specifically, a list of name/value pairs.
EXAMPLE:
List<string> NVList = new List<string>();
NVList.Add("color=blue");
...
3) Note that .Net has a specialized "NameValueCollection" class that might be IDEAL for you:
http://msdn.microsoft.com/en-us/library/system.collections.specialized.namevaluecollection.aspx
Assuming you have your initial dictionary (mapping your keys to values) already you can use some Linq to convert it into a reverse dictionary without having to create that reverse dictionary by hand.
var newDict = initialDict.Select(x=>x.Value).Distinct().ToDictionary(x=>x, x=> initialDict.Where(kvp=>kvp.Value == x).Select(kvp=>kvp.Key));
Select the distinct originalValues from your original dictionary and use those as your newKeys. Your newValues are the set of your originalKeys that mapped to each originalValue/newKey.
Example: https://dotnetfiddle.net/dhwUSC
Given an initial dictionary of
var initialDict = new Dictionary<int, string>{
{1, "Value"},
{2, "Value"},
{3, "Value"},
{4, "Value"},
{5, "Value2"}
};
the above function returns
Value: {1, 2, 3, 4}
Value2: {5}
I have two arrays, x and y, where y is the value of the tens of every element in x. Now, I want to sort y. But, the order of y will be different of x's. So, I can't tell after sorting which element in y was related to, for instance, x[0].
I want a "double sorting" maybe.
Array.Sort has an overload that accepts two arrays; one for the keys, and one for the items. The items of both are sorted according to the keys array:
int[] keys = { 1, 4, 3, 2, 5 };
string[] items = { "abc", "def", "ghi", "jkl", "mno" };
Array.Sort(keys, items);
foreach (int key in keys) {
Console.WriteLine(key); // 1, 2, 3, 4, 5
}
foreach (string item in items) {
Console.WriteLine(item); // abc, jkl, ghi, def, mno
}
So in your case, it sounds like you want:
Array.Sort(y,x); // or Sort(x,y); - it isn't 100% clear
How about?
var selectedArr = new int[] { 1, 3, 5, 7, 9 };
var unorderArr = new int[] { 9, 7, 5, 3, 1 };
var orderedArr = unorderArr.OrderBy(o => selectedArr.IndexOf(o));
If we have two arrays of complex objects and want to sort them according to one of the two arrays then we can use the next approach:
// We want to sort "people" array by "Name" and
// accordingly to it reorder "countries" array.
Person[] people = new Person[]
{
new Person {Name = "Fill"},
new Person {Name = "Will"},
new Person {Name = "Bill"},
};
Country[] countries = new Country[]
{
new Country {Name = "Canada"},
new Country {Name = "UK"},
new Country {Name = "USA"}
};
// Here we sort "people" array, but together with each "Person"
// in sorted array we store its "index" in unsorted array. Then we
// will use this "index" to reorder items in "countries" array.
var sorted = people
.Select((person, index) => new {person, index})
.OrderBy(x => x.person.Name)
.ToArray();
// Here "people" array is sorted by "Name", and
// "contries" array is reordered accordingly to it.
people = sorted.Select(x => x.person).ToArray();
countries = sorted.Select(x => countries[x.index]).ToArray();
Another approach is to use overload of the method Array.Sort with IComparer. At first we should implement IComparer:
private class PeopleComparer : IComparer<Person>
{
public int Compare(Person x, Person y)
{
return x.Name.CompareTo(y.Name);
}
}
And then we can sort two our arrays:
Array.Sort(people, countries, new PeopleComparer());
Here is complete sample that demonstrates these two approaches.
If y is always the tens value of x, y probably shouldn't exist - you should probably just calculate it's value directly off of x when needed.
In general, sorting parallel arrays is only possible (without hand rolling a sort algorithm) when the sort algorithm takes a custom "swap" function, which you can implement in terms of swapping elements in both arrays simultaneously. std::sort in C++ and qsort in C don't allow this.
Also in the general case, consider a single array where the element is a pair of items, rather than a parallel array for each item. This makes using "standard" algorithms easier.