Can I randomize the sequence of items in an ObservableCollection? - observablecollection

I have an ObservableCollection with objects. I want to randomize the order of the collection. How can I do that?

You could use an extension method to do that. You can add this class to you project to provide an extension method for collections. It's a simple shuffle.
public static class ShuffleExtension
{
    public static void Shuffle<T>(this IList<T> list)
    {
        Random rng = new Random();
        int n = list.Count;
        while (n > 1)
        {
            n--;
            int k = rng.Next(n + 1);
            T value = list[k];
            list[k] = list[n];
            list[n] = value;
        }
    }
}
To use, call yourcollection.Shuffle().

Related

How to decorate the final class DocumentGenerator

I am having problems to decorate the final class "DocumentGenerator" (in vendor/shopware/core/Checkout/Document/Service/DocumentGenerator.php) and overwrite the "generate" function inside of it.
I tried to decorate it the usual way, but an error is thrown because the "DocumentController" class excepts the original class and not my decorated one?
Argument 2 passed to Shopware\Core\Checkout\Document\DocumentGeneratorController::__construct() must be an instance of Shopware\Core\Checkout\Document\Service\DocumentGenerator
Its also not possible to extend from the class in my decorated class, because the "DocumentGenerator" is a final class.
My goal is to execute additional code, after an order document is generated. Previously I successfully used to decorate the "DocumentService" Class, but its marked as deprecated and shouldnt be used anymore. Also the "DocumentGenerator" class is used for the new "bulkedit" function for documents as of Version 6.4.14.0
I'm grateful for every tip.
As #j_elfering already wrote it's by design that you should not extend that class and therefore also shouldn't decorate it.
To offer a potential alternative:
Depending on what you want to do after a document has been generated it might be enough to add a subscriber to listen to document.written, check if it was a new document created and then work with the data from the payload for fetching/persisting data depending on that.
public static function getSubscribedEvents()
{
return [
'document.written' => 'onDocumentWritten',
];
}
public function onDocumentWritten(EntityWrittenEvent $event): void
{
foreach ($event->getWriteResults() as $result) {
if ($result->getOperation() !== EntityWriteResult::OPERATION_INSERT) {
// skip if the it's not a new document created
continue;
}
$payload = $result->getPayload();
// do something with the payload
}
}
Probably not what you want to hear but: The service is final in purpose as it is not intended to be decorated.
So the simple answer is you can't. Depending on your use case there may be other ways that don't rely on decoration.

In Kotlin, how to create a single object that has all the features that another class/interface has?

I have a Deck object that has a Set member:
object Deck {
val cardSet = mutableSetOf<Card>()
// other useful functions here...
}
Now I can use it in main() like this:
Deck.cardSet.someFunctionSetHas() // e.g. forEach, map, filter, isEmpty...
But would be more intuitive to use it like the following, and that is what I exactly want:
Deck.isEmpty()
If I try object Deck: Set<Card> { }, IDEA asks me to implement some method manually (contains(), containsAll(), isEmpty(), iterator()) and size member. I want the Deck object work as a mutableSet variable declared like:
val mset = mutableSetOf<Card>()
In this case I do not need to implement those in-built methods manually. This is the behavior I want for the Deck object, plus my own declared functions.
You can do it this way:
private val cardSet = mutableSetOf<Card>()
object Deck : MutableSet<Card> by cardSet {
// other useful functions here...
}
You can subclass an existing MutableSet implementation like HashSet:
object Deck: HashSet<Card>() {
// other useful functions here...
}
Delegation is probably the best way, as given in another answer.  But for completeness, it might be worth mentioning the java.lang.reflect.Proxy class, which can be used to create a dynamic proxy; that's how such things are done in plain Java, and so of course Kotlin/JVM can do it that way too.

how to cast/convert a Collection<T> to an Collection<U>

is there an easy way to do this whiteout using a loops?
how my classes looks like
class T
{
//some stuff
}
class U
{
//some stuff
public U(T myT)
{
//some stuff
}
}
i found on my research the following method List.ConvertAll but it is only for List now i want to know if someone knows a way to achieve this for Collections.
i would prefer a generic solution but anything that solve this in a performant way.
You can use a LINQ select for this:
var enumerableOfU = collectionOfT.Select(t => new U(t));
If you want to enumerate enumerableOfU multiple times, you should append .ToList() or .ToArray() after the Select.
Please note that this internally still uses loops, but you don't have to write it yourself.

Ext.XTemplate loop through object

my controller returns data like this:
{
"success":true,
"data":{
"35":{
"msg":{
"32":{
"module_id":"35",
"alert_id":"32",
"alert_datetime":"2012-11-28 16:19:19",
"param1_type":"imo",
"param1_value":"453465",
"param2_type":"",
"param2_value":"0",
"param3_type":"",
"param3_value":"0",
"msg":"triiiis dve",
"count":1
},
"33":{
"module_id":"35",
"alert_id":"33",
"alert_datetime":"2012-10-28 00:00:00",
"param1_type":"imo",
"param1_value":"54984",
"param2_type":"",
"param2_value":"0",
"param3_type":"",
"param3_value":"0",
"msg":"triis tri",
"count":1
}
}
},
"42":{
"msg":{
"1":{
"module_id":"42",
"alert_id":"1",
"alert_datetime":"2012-10-28 16:19:19",
"param1_type":"imo",
"param1_value":"9281906",
"param2_type":"",
"param2_value":"0",
"param3_type":"",
"param3_value":"0",
"msg":"",
"count":1
}
}
},
"39":{
"msg":{
"2":{
"module_id":"39",
"alert_id":"2",
"alert_datetime":"2012-10-28 12:36:31",
"param1_type":"imo",
"param1_value":"65464546",
"param2_type":"",
"param2_value":"0",
"param3_type":"",
"param3_value":"0",
"msg":"",
"count":1
}
}
}
}
}
After that I do this
that.tpl.overwrite(that.el, Ext.decode(response).data);
The problem is that I can't loop through the result object keys... I know how to loop through objects with pre-defined key names, but mine are dynamicaly generated...
Will appreciate some help, thanks!
I am assuming you have an idea of the depth of nesting (4 levels below the "data" element in this case):
You could loop through the data with Ext.Object.each (maybe there are some query methods for this too, not sure), looping through each element's children too. In case you use Ext.data.Model instances, you can use the Ext.data.association links to loop through the data.
In that case you could make a different template for each level and insert the result of each template in the template of the level above.
It sounds more difficult than it actually is I think.
foreach in templates is currently indeed only available for support subscribers.

IEnumerable<T>.ConvertAll & DDD

I have an interesting need for an extension method on the IEumerable interface - the same thing as List.ConvertAll. This has been covered before here and I found one solution here. What I don't like about that solution is he builds a List to hold the converted objects and then returns it. I suspect LINQ wasn't available when he wrote his article, so my implementation is this:
public static class IEnumerableExtension
{
public static IEnumerable<TOutput> ConvertAll<T, TOutput>(this IEnumerable<T> collection, Func<T, TOutput> converter)
{
if (null == converter)
throw new ArgumentNullException("converter");
return from item in collection
select converter(item);
}
}
What I like better about this is I convert 'on the fly' without having to load the entire list of whatever TOutput's are. Note that I also changed the type of the delegate - from Converter to Func. The compilation is the same but I think it makes my intent clearer - I don't mean for this to be ONLY type conversion.
Which leads me to my question: In my repository layer I have a lot of queries that return lists of ID's - ID's of entities. I used to have several classes that 'converted' these ID's to entities in various ways. With this extension method I am able to boil all that down to code like this:
IEnumerable<Part> GetBlueParts()
{
IEnumerable<int> keys = GetBluePartKeys();
return keys.ConvertAll<Part>(PartRepository.Find);
}
where the 'converter' is really the repository's Find-by-ID method. In my case, the 'converter' is potentially doing quite a bit. Does anyone see any problems with this approach?
The main issue I see with this approach is it's completely unnecessary.
Your ConvertAll method is nothing different than Enumerable.Select<TSource,TResult>(IEnumerable<TSource>, Func<TSource,TResult>), which is a standard LINQ operator. There's no reason to write an extension method for something that already is in the framework.
You can just do:
IEnumerable<Part> GetBlueParts()
{
IEnumerable<int> keys = GetBluePartKeys();
return keys.Select<int,Part>(PartRepository.Find);
}
Note: your method would require <int,Part> as well to compile, unless PartRepository.Find only works on int, and only returns Part instances. If you want to avoid that, you can probably do:
IEnumerable<Part> GetBlueParts()
{
IEnumerable<int> keys = GetBluePartKeys();
return keys.Select(i => PartRepository.Find<Part>(i)); // I'm assuming that fits your "Find" syntax...
}
Why not utilize the yield keyword (and only convert each item as it is needed)?
public static class IEnumerableExtension
{
public static IEnumerable<TOutput> ConvertAll<T, TOutput>
(this IEnumerable<T> collection, Func<T, TOutput> converter)
{
if(null == converter)
throw new ArgumentNullException("converter");
foreach(T item in collection)
yield return converter(item);
}
}

Resources