There is a List<Integer> tabulist that contains values [2,0,5].
Also, there is a List this.getRoutes() which contains keys [0,1,2,3,4,5].
I need to delete elements [2,0,5] from this.getRoutes().
So, as a result I must get the following entries in this.getRoutes():
[1,3,4]
Here is my code:
iter = this.getRoutes().iterator();
while(iter.hasNext())
{
Route r = iter.next();
if (tabulist.contains(r.getRouteKey()))
{
iter.remove();
}
}
The problem is that r.getRouteKey() is always 0. Therefore, I am always deleting the first elements from this.getRoutes(). I don't understand why the iterator does not move to [1,2,3,4,5].
How to solve this issue? Maybe I should also delete values from tabulist?
I didn't test my code, but here are 3 variations on the theme. You should test them in case I made a mistake, but they give an idea of the general idea.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
public class Class1
{
public static List<int> RemoveItems1(List<int> OriginalValues, List<int> ValuesToRemove)
{
List<int> result = new List<int>();
foreach (object item_loopVariable in OriginalValues) {
item = item_loopVariable;
if ((!ValuesToRemove.Contains(item))) {
result.Add(item);
}
}
return result;
}
public static List<int> RemoveItems2(List<int> OriginalValues, List<int> ValuesToRemove)
{
List<int> result = OriginalValues;
foreach (object item_loopVariable in ValuesToRemove) {
item = item_loopVariable;
if ((OriginalValues.Contains(item))) {
result.Remove(item);
}
}
return result;
}
public static List<int> RemoveItems3(List<int> OriginalValues, List<int> ValuesToRemove)
{
List<int> result = OriginalValues;
foreach (object item_loopVariable in from item1 in ValuesToRemovewhere (OriginalValues.Contains(item1))) {
item = item_loopVariable;
result.Remove(item);
}
return result;
}
}
The first one adds only elements to get to a result. Like I said in my comment.
The second one removes elements from a result that is set to the parameter Originalvalues. The last one is basically the same as number two, but uses LINQ.
I'm using static methods because then this can be used in any situation and you don't need to instantiate a class to do this. Which adds extra unnecessary code.
Related
I'm on a page SomePage?A=a&B=b&...
I want to construct a URL that has all of the current GET parameters plus some more from an IDictionary<string, string> that I have.
The tag helper asp-all-route-data="#myDictionary" will get set the parameters from my dictionary, but I don't understand:
how to create a link with all of the current parameters; or
how to add extra parameters to such a link.
Well this works, but I think it's a bit crap because:
this feels like a really obvious thing to want to so so I don't believe that there isn't an out of the box way to do it,
I can't get the extension method to work -- it has to be called as MakeGet(this, d) rather than just MakeGet(d), and
Shouldn't we be using something like a NameValueCollection that models multiple keys as are supported in GET?
public static IDictionary<string, string> MakeGet<T>(this RazorPage p, IDictionary<string, T> d)
{
return MakeGet(p, d.ToDictionary(z => z.Key, z => { try { return z.ToString(); } catch { return null; } }));
}
public static IDictionary<string, string> MakeGet(this RazorPage p, IDictionary<string, string> d)
{
Dictionary<string, string> result = new Dictionary<string, string>();
foreach (string k in d.Keys)
{
if (!string.IsNullOrWhiteSpace(d[k]))
{
result.Add(k, d[k]);
}
}
IQueryCollection get = p.ViewContext.HttpContext.Request.Query;
foreach (KeyValuePair<string, StringValues> q in p.ViewContext.HttpContext.Request.Query)
{
if (!result.Keys.Contains(q.Key))
{
result.Add(q.Key, string.Join(",", q.Value));
}
}
return result;
}
The next problem is how to subsequently remove a parameter in the controller in order to do a redirect.
public async Task<IActionResult> OnGetTableDeleteAsync()
{
// Need to remove parameter LineNumber.
return RedirectToAction("Get");
}
Well this is what I've come up with for the parameter removal.
public static RouteValueDictionary QueryWithout(this PageModel p, params string[] remove)
{
RouteValueDictionary q = new RouteValueDictionary();
foreach (var kv in (QueryHelpers.ParseQuery(p.Request.QueryString.Value).Where(z => !remove.Contains(z.Key))))
{
q.Add(kv.Key, kv.Value);
}
return q;
}
Being used like this
public async Task<IActionResult> OnGetTableDeleteAsync(int lineNumber)
{
ImportStagingRecord i = _context.ImportStagingRecords.Find(FileId, lineNumber);
if( i != null)
{
_context.ImportStagingRecords.Remove(i);
await _context.SaveChangesAsync();
}
Microsoft.AspNetCore.Routing.RouteValueDictionary q = BaseUri.QueryWithout(this, "LineNumber", "handler");
return RedirectToAction("", q);
}
Again, I think it's crap.
(The query string contains lots of parameters for sorting, filtering, and paging the table of ImportStagingRecords which need to be preserved across requests.)
I'm using the code from azure project, when CosmosDB is created first time. It has a nice generic GetItemsAsync method.
I have modified it a little to have following:
public static async Task<List<T>> GetItemsAsync(Expression<Func<T, bool>> predicate, int maxItemCount = -1)
{
IDocumentQuery<T> query = client.CreateDocumentQuery<T>(
UriFactory.CreateDocumentCollectionUri(DatabaseId, CollectionId),
new FeedOptions { MaxItemCount = maxItemCount })
.Where(predicate)
.AsDocumentQuery();
List<T> results = new List<T>();
while (query.HasMoreResults)
{
results.AddRange(await query.ExecuteNextAsync<T>());
if (maxItemCount != -1)
{
break;
}
}
return results;
}
What I want to do is, in some calls to this method, I need to add OrderBy query. The problem is I have couple collections in same CosmosDB and fields are different. When I want to list one of the collections I just want to get latest ones.
So in this example, I actually send count as 50 so I will get only 50, but I also want to get recent ones. The above code returns oldest 50 as expected. Is there any solution this? I'm guessing there might be a way to get latest data first and when I call for 50, it would be latest 50 records.
Other thing I tried, was to create another method called GetItemsWithOrderByAsync and tried to give Expression>, but it requires so much modification in whole class to support TKey.
Ok, after playing around, I came up with the following as a solution. Created new method and:
public static async Task<List<T>> GetItemsWithOrderByAsync(Expression<Func<T, bool>> predicate, Expression<Func<T, object>> orderByPredicated, int maxItemCount = -1)
{
IDocumentQuery<T> query = client.CreateDocumentQuery<T>(
UriFactory.CreateDocumentCollectionUri(DatabaseId, CollectionId),
new FeedOptions { MaxItemCount = maxItemCount }).
Where(predicate).
OrderByDescending(orderByPredicated).
AsDocumentQuery();
List<T> results = new List<T>();
while (query.HasMoreResults)
{
results.AddRange(await query.ExecuteNextAsync<T>());
if (maxItemCount != -1)
{
break;
}
}
return results;
}
Just came across the latest build of Mono.CSharp and love the promise it offers.
Was able to get the following all worked out:
namespace XAct.Spikes.Duo
{
class Program
{
static void Main(string[] args)
{
CompilerSettings compilerSettings = new CompilerSettings();
compilerSettings.LoadDefaultReferences = true;
Report report = new Report(new Mono.CSharp.ConsoleReportPrinter());
Mono.CSharp.Evaluator e;
e= new Evaluator(compilerSettings, report);
//IMPORTANT:This has to be put before you include references to any assemblies
//our you;ll get a stream of errors:
e.Run("using System;");
//IMPORTANT:You have to reference the assemblies your code references...
//...including this one:
e.Run("using XAct.Spikes.Duo;");
//Go crazy -- although that takes time:
//foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
//{
// e.ReferenceAssembly(assembly);
//}
//More appropriate in most cases:
e.ReferenceAssembly((typeof(A).Assembly));
//Exception due to no semicolon
//e.Run("var a = 1+3");
//Doesn't set anything:
//e.Run("a = 1+3;");
//Works:
//e.ReferenceAssembly(typeof(A).Assembly);
e.Run("var a = 1+3;");
e.Run("A x = new A{Name=\"Joe\"};");
var a = e.Evaluate("a;");
var x = e.Evaluate("x;");
//Not extremely useful:
string check = e.GetVars();
//Note that you have to type it:
Console.WriteLine(((A) x).Name);
e = new Evaluator(compilerSettings, report);
var b = e.Evaluate("a;");
}
}
public class A
{
public string Name { get; set; }
}
}
And that was fun...can create a variable in the script's scope, and export the value.
There's just one last thing to figure out... how can I get a value in (eg, a domain entity that I want to apply a Rule script on), without using a static (am thinking of using this in a web app)?
I've seen the use compiled delegates -- but that was for the previous version of Mono.CSharp, and it doesn't seem to work any longer.
Anybody have a suggestion on how to do this with the current version?
Thanks very much.
References:
* Injecting a variable into the Mono.CSharp.Evaluator (runtime compiling a LINQ query from string)
* http://naveensrinivasan.com/tag/mono/
I know it's almost 9 years later, but I think I found a viable solution to inject local variables. It is using a static variable but can still be used by multiple evaluators without collision.
You can use a static Dictionary<string, object> which holds the reference to be injected. Let's say we are doing all this from within our class CsharpConsole:
public class CsharpConsole {
public static Dictionary<string, object> InjectionRepository {get; set; } = new Dictionary<string, object>();
}
The idea is to temporarily place the value in there with a GUID as key so there won't be any conflict between multiple evaluator instances. To inject do this:
public void InjectLocal(string name, object value, string type=null) {
var id = Guid.NewGuid().ToString();
InjectionRepository[id] = value;
type = type ?? value.GetType().FullName;
// note for generic or nested types value.GetType().FullName won't return a compilable type string, so you have to set the type parameter manually
var success = _evaluator.Run($"var {name} = ({type})MyNamespace.CsharpConsole.InjectionRepository[\"{id}\"];");
// clean it up to avoid memory leak
InjectionRepository.Remove(id);
}
Also for accessing local variables there is a workaround using Reflection so you can have a nice [] accessor with get and set:
public object this[string variable]
{
get
{
FieldInfo fieldInfo = typeof(Evaluator).GetField("fields", BindingFlags.NonPublic | BindingFlags.Instance);
if (fieldInfo != null)
{
var fields = fieldInfo.GetValue(_evaluator) as Dictionary<string, Tuple<FieldSpec, FieldInfo>>;
if (fields != null)
{
if (fields.TryGetValue(variable, out var tuple) && tuple != null)
{
var value = tuple.Item2.GetValue(_evaluator);
return value;
}
}
}
return null;
}
set
{
InjectLocal(variable, value);
}
}
Using this trick, you can even inject delegates and functions that your evaluated code can call from within the script. For instance, I inject a print function which my code can call to ouput something to the gui console window:
public delegate void PrintFunc(params object[] o);
public void puts(params object[] o)
{
// call the OnPrint event to redirect the output to gui console
if (OnPrint!=null)
OnPrint(string.Join("", o.Select(x => (x ?? "null").ToString() + "\n").ToArray()));
}
This puts function can now be easily injected like this:
InjectLocal("puts", (PrintFunc)puts, "CsInterpreter2.PrintFunc");
And just be called from within your scripts:
puts(new object[] { "hello", "world!" });
Note, there is also a native function print but it directly writes to STDOUT and redirecting individual output from multiple console windows is not possible.
I built a custom collector for Lucene.Net, but I can't figure out how to order (or page) the results. Everytime Collect gets called, I can add the result to an internal PriorityQueue, which I understand is the correct way to do this.
I extended the PriorityQueue, but it requires a size parameter on creation. You have to call Initialize in the constructor and pass in the max size.
However, in a collector, the searcher just calls Collect when it gets a new result, so I don't know how many results I have when I create the PriorityQueue. Based on this, I can't figure out how to make the PriorityQueue work.
I realize I'm probably missing something simple here...
PriorityQueue is not SortedList or SortedDictionary.
It is a kind of sorting implementation where it returns the top M results(your PriorityQueue's size) of N elements. You can add with InsertWithOverflow as many items as you want, but it will only hold only the top M elements.
Suppose your search resulted in 1000000 hits. Would you return all of the results to user?
A better way would be to return the top 10 elements to the user(using PriorityQueue(10)) and
if the user requests for the next 10 result, you can make a new search with PriorityQueue(20) and return the next 10 elements and so on.
This is the trick most search engines like google uses.
Everytime Commit gets called, I can add the result to an internal PriorityQueue.
I can not undestand the relationship between Commit and search, Therefore I will append a sample usage of PriorityQueue:
public class CustomQueue : Lucene.Net.Util.PriorityQueue<Document>
{
public CustomQueue(int maxSize): base()
{
Initialize(maxSize);
}
public override bool LessThan(Document a, Document b)
{
//a.GetField("field1")
//b.GetField("field2");
return //compare a & b
}
}
public class MyCollector : Lucene.Net.Search.Collector
{
CustomQueue _queue = null;
IndexReader _currentReader;
public MyCollector(int maxSize)
{
_queue = new CustomQueue(maxSize);
}
public override bool AcceptsDocsOutOfOrder()
{
return true;
}
public override void Collect(int doc)
{
_queue.InsertWithOverflow(_currentReader.Document(doc));
}
public override void SetNextReader(IndexReader reader, int docBase)
{
_currentReader = reader;
}
public override void SetScorer(Scorer scorer)
{
}
}
searcher.Search(query,new MyCollector(10)) //First page.
searcher.Search(query,new MyCollector(20)) //2nd page.
searcher.Search(query,new MyCollector(30)) //3rd page.
EDIT for #nokturnal
public class MyPriorityQueue<TObj, TComp> : Lucene.Net.Util.PriorityQueue<TObj>
where TComp : IComparable<TComp>
{
Func<TObj, TComp> _KeySelector;
public MyPriorityQueue(int size, Func<TObj, TComp> keySelector) : base()
{
_KeySelector = keySelector;
Initialize(size);
}
public override bool LessThan(TObj a, TObj b)
{
return _KeySelector(a).CompareTo(_KeySelector(b)) < 0;
}
public IEnumerable<TObj> Items
{
get
{
int size = Size();
for (int i = 0; i < size; i++)
yield return Pop();
}
}
}
var pq = new MyPriorityQueue<Document, string>(3, doc => doc.GetField("SomeField").StringValue);
foreach (var item in pq.Items)
{
}
The reason Lucene's Priority Queue is size limited is because it uses a fixed size implementation that is very fast.
Think about what is the reasonable maximum number of results to get back at a time and use that number, the "waste" for when the results are few is not that bad for the benefit it gains.
On the other hand, if you have such a huge number of results that you cannot hold them, then how are you going to be serving/displaying them? Keep in mind that this is for "top" hits so as you iterate through the results you will be hitting less and less relevant ones anyway.
I've looked all around, and can't quite figure this one out, and my multitude of trial and error attempts have all been useless.
I have a list of user names (we'll call 'original list') one object is returning
I have a list of user names (we'll call 'filtration list') another object is returning
I am testing a method that returns all of the items from the original list not in the filtration list.
Ideally what I want is something like
Assert.That(returnedList, Has.No.Members.In(filtrationList))
So far the only thing I can do is iterate over the filtrationList and do
Assert.That(returnedList, Has.None.EqualTo(filteredUser))
With nunit you can create any custom constraint.
If you want to verify two collections for intersection, you can create something like this:
public class Intersects : CollectionConstraint
{
private IEnumerable _collection2;
public Intersects(IEnumerable collection2)
: base(collection2)
{
_collection2 = collection2;
}
public static Intersects With(IEnumerable arg)
{
return new Intersects(arg);
}
protected override bool doMatch(IEnumerable collection)
{
foreach (object value in collection)
{
foreach (object value2 in _collection2)
if (value.Equals(value2))
return true;
}
return false;
}
public override void WriteDescriptionTo(MessageWriter writer)
{
//You can put here something more meaningful like items which should not be in verified collection.
writer.Write("intersecting collections");
}
}
usage is pretty simple:
string[] returnedList = new string[] { "Martin", "Kent", "Jack"};
List<string> filteredUsers = new List<string>();
filteredUsers.Add("Jack");
filteredUsers.Add("Bob");
Assert.That(returnedList, Intersects.With(filteredUsers));