In my C# winforms project, I wanted to update a specific index based position in a collection (named List l1 here).
I tried below code:
l1.Where((s, i1) => i1 == intvalue).Select(s => { if (s > 0) s = -1; return s; };
I wanted to set value at invalue index to -1 in the list l1, but when I do so with above statement the value in l1 is not changed. Please help! I am new to Linq and have searched the topic 'index based change of value in a collection' everywhere, but can't resolve my problem as it involves BigInteger type and I have so many elements in the list that their total count passes the allowed max value for int type in c#. So when I type l1[intvalue] it says can't convert BigInteger to int for index position.
Thanks
LINQ is Language INtegrated Queries. It's purpose is querying data. If you want to modify list item:
if (l1[intvalue] > 0)
l1[intvalue] = -1;
Also I'd like to explain why your query is not changing list.
On first step you are selecting list items by some condition. Very strange condition by the way. If you want to select item by index, there is operator ElementAt.
Then you are doing projection. I.e. you are calling anonymous method which accepts each selected item and produce some result. Each item passed to that method as s argument. And when you are assigning -1 to s you are actually assigning value to method argument. That does not affect items in the list. Even if your list will contain items of reference type instead of integers, assigning value to method argument will just change where argument variable points. It will not change references in original list. Though you still can modify items of reference type. But such side-effects in projection methods are not good practice.
Related
With a normal array, I can use the arrayname.find_index('whatimlookingfor') to get the position within the array.
I can't figure out how to do this when the elements of the array are Struct's.
Scenario: I have a struct that consists of an ID and the Filename. In one function I need to find within that array the ID of a different file than the one I'm currently processing. I know the other filename, so what I was hoping that I could do something like:
arrayname.filename.find_index(parsedfilename)
But this obviously fails. Without iterating through the entire array is there a way to quickly reference the index of where the match happens? Or am I out of luck because the array is a collection of structs?
index (same as find_index) takes a block in which you can code up any true/false logic for your finder. To find the index of the first item whose filename does not match parsedfilename...
found_index = items.index { |item| item.filename != parsedfilename }
Many methods which work with Arrays and Enumerables also take blocks.
Laravel's Collection class (v5.5) has a sortBy() method that sorts everything similar to if you had used a SQL ORDER BY statement, except there is one striking difference: a relational database will put NULL values at the end when sorting ascending (or at least PostgreSQL does), but Laravel's sortBy() method puts NULL values first.
So how do I get those NULL values to be sorted last instead of first when using the Collection::sortBy() method? PLEASE NOTE: I cannot change the database query itself! MY ONLY OPTION is to sort the Collection itself within PHP. I absolutely cannot do this at the database level in my situation.
There is a similar question on Stack Overflow here but the solution OP found was kind of a hack and does not work in my situation, because I need it to work for varchars.
NOTE: I realize sortBy() accepts a Closure for the first argument but there is zero explanation in the documentation about the arguments this closure receives (which "key" is $key?), nor does it explicitly say what the closure is supposed to return in order to determine the sort order. (I'm assuming it should return an integer representing the order, but I do not know how to make that work for me with multiple NULL values.)
The sortBy method accepts a field on which to sort, in ascending order. So if you had a collection of App\User objects, you could pass in say first_name and that would sort by each user's first name.
If your logic is more complex, and you wanted to sort on something that isn't strictly a field of each item in your collection you may pass a closure instead. The first parameter passed to the closure is the actual item. You should return a value that you want to be sorted from the closure. Let's say in your collection of App\User objects, you wanted to sort by the last letter of each person's first name:
$users->sortBy(function ($item) {
return substr($item->first_name, -1);
});
The second parameter is the key, which is the key of the collection, or the underlying array it represents. If you've retrieved a collection from the database, this will likely be a numeric index, but if you had a different collection or you decided to re-key the collection by say, the user's email address (Using keyBy), then that is what is passed.
When it comes to sticking all of your null values at the end of the sorted result set, I would suggest using the sort method instead of sortBy. When you pass a closure to sort, it accepts two items, representing two items from your collection to be sorted. In the case of your collection of App\User objects, each item would an instance of App\User. This gives you total control on how two objects are compared and therefore total control over the order.
You should return -1 (or a negative value) if the first item is considered to be less than the second, you should return 0 if the two items are to be considered equal and 1 (or a positive value) if the first item is considered to be greater than the second.
$users->sort(function ($a, $b) {
// Return -1, 0 or 1 here
});
That should allow you to implement your logic. To ensure null values are moved to the end, just return 1 every time whatever you're interested in from $a is null. Similarly, if whatever you're interested in from $b is null, return -1 and if whatever you're interested in from both $a and $b are null, return 0.
What is the best data structure to check if the number of elements of different types of objects is the same?
For example, if I have
2 a's
3 b's
3 c's
The number of elements of the different types of objects is not the same.
If I have
2 a's
2 b's
2 c's
then this is the same.
What is the best data structure that allows you do this in O(1) time and how would you implement it?
One method is to use two dictionaries to be able to do it in O(1) dynamically.
The first maps each type to a count, {a:2,b:3,c:3}. The second maps each count to a set of types with that count. {2:{a},3:{b,c}}. If the size of the second dictionary is less than 2 (0 or 1) then clearly all types have the same count as if that was not the case then there would be at least two key-item pairs in that dictionary, presuming that the dictionary is updated when the counts change.
Adding a type just means adding it to each dictionary.
Removing a type just means removing it from each dictionary.
Updating a type requires first updating the second dictionary by removing the previous count (obtained from the first dictionary) and adding the current count, after which the first dictionary is updated.
Dictionary<Type, int> typeCounts = new Dictionary<Type, int>();
// read and store type counts
Type type = typeof(A);
if (typeCounts.Contains(type))
{
typeCounts[type]++;
}
else
{
typeCounts.Add(type, 1);
}
// populate type counts by type and finally:
if (typeCounts[typeA] == typeCounts[typeB])
{
// so on
}
I'm kinda new to XPath and I've found that to get the max attribute number I can use the next statement: //Book[not(#id > //Book/#id) and it works quite well.
I just can't understand why does it return max id instead of min id, because it looks like I'm checking whether id of a node greater than any other nodes ids and then return a Book where it's not.
I'm probably stupid, but, please, someone, explain :)
You're not querying for maximum values, but for minimum values. Your query
//Book[not(#id > //Book/#id)
could be translated to natural language as "Find all books, which do not have an #id that is larger than any other book's #id". You probably want to use
//Book[not(#id < //Book/#id)
For arbitrary input you might have wanted to use <= instead, so it only returns a single maximum value (or none if it is shared). As #ids must be unique, this does not matter here.
Be aware that //Book[#id > //Book/#id] is not equal to the query above, although math would suggest so. XPath's comparison operators adhere to a kind of set-semantics: if any value on the left side is larger than any value on the right side, the predicate would be true; thus it would include all books but the one with minimum #id value.
Besides XPath 1.0 your function is correct, in XPath 2.0:
/Books/Book[id = max(../Book/id)]
The math:max function returns the maximum value of the nodes passed as the argument. The maximum value is defined as follows. The node set passed as an argument is sorted in descending order as it would be by xsl:sort with a data type of number. The maximum is the result of converting the string value of the first node in this sorted list to a number using the number function.
If the node set is empty, or if the result of converting the string values of any of the nodes to a number is NaN, then NaN is returned.
The math:max template returns a result tree fragment whose string value is the result of turning the number returned by the function into a string.
results.Where(x=>x.Members.Any(y=>members.Contains(y.Name.ToLower())
I happened to see this query in internet. Can anyone explain this query please.
suggest me a good LINQ tutorial for this newbie.
thank you all.
Edited:
what is this x and y stands for?
x is a single result, of the type of the elements in the results sequence.
y is a single member, of the type of the elements in the x.Members sequence.
These are lambda expressions (x => x.whatever) that were introduced into the language with C# 3, where x is the input, and the right side (x.whatever) is the output (in this particular usage scenario).
An easier example
var list = new List<int> { 1, 2, 3 };
var oddNumbers = list.Where(i => i % 2 != 0);
Here, i is a single int item that is an input into the expression. i % 2 != 0 is a boolean expression evaluating whether the input is even or odd. The entire expression (i => i % 2 != 0) is a predicate, a Func<int, bool>, where the input is an integer and the output is a boolean. Follow? As you iterate over the query oddNumbers, each element in the list sequence is evaluated against the predicate. Those that pass then become part of your output.
foreach (var item in oddNumbers)
Console.WriteLine(item);
// writes 1, 3
Its a lambda expression. Here is a great LINQ tutorial
Interesting query, but I don't like it.
I'll answer your second question first. x and y are parameters to the lambda methods that are defined in the calls to Where() and Any(). You could easy change the names to be more meaningful:
results.Where(result =>
result.Members.Any(member => members.Contains(member.Name.ToLower());
And to answer your first question, this query will return each item in results where the Members collection has at least one item that is also contained in the Members collection as a lower case string.
The logic there doesn't make a whole lot of sense to me with knowing what the Members collection is or what it holds.
x will be every instance of the results collection. The query uses lambda syntax, so x=>x.somemember means "invoke somemember on each x passed in. Where is an extension method for IEnumerables that expects a function that will take an argument and return a boolean. Lambda syntax creates delegates under the covers, but is far more expressive for carrying out certain types of operation (and saves a lot of typing).
Without knowing the type of objects held in the results collection (results will be something that implements IEnumerable), it is hard to know exactly what the code above will do. But an educated guess is that it will check all the members of all the x's in the above collection, and return you an IEnumerable of only those that have members with all lower-case names.