Does Automapper preserve mapped list item order? - automapper

I could not find information on List item mapping order in Automapper's documentation or unit tests. If I try to map a new List<int>() { 1, 2, 3, 4 } to another List<int>, can I be sure that a new list will always have items { 1, 2, 3, 4 } in the same order?
Automapper's unit tests regarding lists only check if a new list contains the items and have no assumptions regarding item order.

Related

Can django AutoField be used for custom increment logic in addition to the separate automatic ID AutoField?

I have the following model:
class Lot(models.Model):
parent_lot_number = models.IntegerField(default=0)
child_lot_number = models.IntegerField(null=True, blank=True)
I want the following behavior:
parent lot number should increment only when the user enters data in a specific form that is creating a new parent
child lot number should increment all the time, within each parent
For example, the following should be valid data for Lot records:
parent_lot_number: 1, child_lot_number: null
parent_lot_number: 1, child_lot_number: 1
parent_lot_number: 1, child_lot_number: 2
parent_lot_number: 2, child_lot_number: null
parent_lot_number: 2, child_lot_number: 1
parent_lot_number: 1, child_lot_number: 3
parent_lot_number: 3, child_lot_number: null
Right now, I have working business logic to do this in my views/forms by getting the max of child_lot_number and parent_lot_number, then assigning the value after the record is created.
Instead, can I accomplish this by removing the default=0 on parent_lot_number and using AutoField? When I set parent_lot_number = models.AutoField() I receive errors that "NOT NULL constraint failed: main_lot.parent_lot_number" or "ValueError: Model main.Lot can't have more than one auto-generated field." because of django's hidden ID column. This is a column I cannot drop.

How to get count of documents that would be added if one selects another aggregation options of an array-field in elastic search

Let's say we have four documents with a tags field. It can contain multiple strings, let's say foo, bar and baz.
docA.tags = ['foo']
docB.tags = ['bar']
docC.tags = ['foo', 'bar']
docD.tags = ['foo', 'baz']
I query the docs using aggregations so I get the four documents and a list of three buckets with the count that matches the specific tag.
buckets = [
{key: 'bar', doc_count: 2}, // docB, docC
{key: 'foo', doc_count: 3}, // docA, docC, docD
{key: 'baz', doc_count: 1} // docD
]
If I now run another query and add one of those tags – lets say foo – as a terms-filter to the query, I only get the docs (docA, docC, docD) that have this tag. That's what I want.
But I also get another list of possible aggregations with updated counts.
buckets = [
{key: 'bar', doc_count: 1}, // docC
{key: 'baz', doc_count: 1}, // docD
]
But these counts don't really match what's happening. They reflect the count of documents that match both of the tags, the one I selected in the first place (foo) AND the one of the bucket (bar or baz).
But if I then select a second tag – let's say baz – I get documents that have been tagged with foo OR baz. That's because I use the terms filter.
So what I really want is this
buckets = [
{key: 'bar', doc_count: 1}, //docB
{key: 'baz', doc_count: 0},
]
How can I achieve that the counts are appropriate. They should reflect the count of documents that would be added if I select the second tag. An example of this is here.
I already tried to use post_filter but that always gives me the first result. Than a min_doc_count-flag to the aggs, but this only shows me the combinations that would result in count=0.
I have a solution for this, but it seem pretty complicated to me. For this I would have to run another request for each aggregation where I invert the filter criteria. So in the upper example I have to make a query to all docs that don't have the tag foo and match the rest of the query. The aggregation results would be exactly what I needed.
It sounds like you're trying to do something a little atypical for facets/aggregations.
(However, it's not invalid... it makes a lot of sense to understand how the size of your selection will change through the application of a filter)
What I think you're asking for is:
Display results for: QUERY AND FILTER
Display term aggregation counts for: QUERY NOT FILTER
You mentioned you're doing subsequent request(s) for counts? You should be able to construct this aggregation request inside your main search request.
Structurally it's:
match: (QUERY) or match_all
aggregations:
filter: { not: (FILTER) }
aggregations: { terms: ... }
post_filter: (FILTER)
That post_filter is executed after the aggregations are calculated (but still applied to the search results) so your results will be what you expect.
The aggregations are working in the scope of the search query alone. (The postfilter has not been applied yet.)
The filter aggregation excludes all documents matching FILTER from the search query results before the Terms Aggregation calculates the counts.
(giving you the left outside edge of the Venn shown above, but just for the counts)

Combine lists that have at least one item in common

I have a list of lists in groovy. Some of the nested lists have certain items in common. I would like for all of the nested lists that have at least one item in common to join into one list, for example:
Extract of my list of lists :
[[buy, order, bought, purchase],
[opinion, point of view],
[opinion, belief],
[buy, purchased],
[buy, order, purchases]]
(The order of nested lists is random)
What I would like to achieve :
[[buy, order, bought, purchase, buy, purchased, buy, order, purchases],
[opinion, point of view, opinion, belief]]
Anybody has any suggestions on how to achieve this?
Thank you!
You can do the following with inject:
def input = [['buy', 'order', 'bought', 'purchase'],
['opinion', 'point of view'],
['opinion', 'belief'],
['buy', 'purchased'],
['buy', 'order', 'purchases']]
input.inject([]) { list, current ->
list.find { it.intersect(current) }?.addAll(current) ?: list << current
list
}
So, find an element in the output list that intersects with the current input list, and if it exists add it to that output list.
If one isn't found, add the input list to the output list

Erroneous Resharper multiple enumeration warning?

This code:
IEnumerable<IEnumerable<int>> numbas = new[] {new[] {0, 1}, new[] {2}, new[] {3, 4, 5}};
var flattened = numbas.SelectMany(a => a);
extracts a single flattened enumerable list of numbers from several sources. Resharper warns that it's possible that a (the second one) is being enumerated multiple times -- but this is silly; each source is being enumerated once only. Yes, the symbol a is going to be enumerated multiple times, but there will be a different source under it each time.
Did I miss something, or is this an erroneous warning coming out of Resharper?
Yes, this is an erroneous warning. You can see if you take a look at the implementation of SelectMany - there's only one enumeration of the nested element:
foreach (TSource element in source) {
foreach (TResult subElement in selector(element)) {
yield return subElement;
}
}
Here's the YouTrack issue for this: http://youtrack.jetbrains.com/issue/RSRP-413613

sort by tags with weight in mongodb and maybe redis

I am trying to list items according to how 'important' their tags are.
Here is an example of an item:
{
name: 'item1',
tags: [1, 2, 3]
}
And here is an example of a tag
{
_id: 1,
name: red,
weight: 0.7
}
I am trying to find out the best way to sort a list of items where a lot of calculations must be made.
I imagine that sorting in real time might not be the best way and resorting to something like redis might be necessary.
By doing so I would store all the data relevant to calculate the sorting positions in redis right ?
Any input will be greatly appreciated!

Resources