sequence operators not supported for type 'system.string' - linq

what is the problem in this query
var ptypes = (from mf in _pagecontext.PagesRefs
let a = mf.nvcr_Slug.Substring(mf.nvcr_Slug.LastIndexOf("/") + 1) // gets everything after /
let b = Regex.Replace(a, #"[\d-]+$", m => m.Value.Replace('-', '=')) // replace last char with =
let cc = (b.Contains('=') ? b.Substring(0, b.IndexOf("=")) : b) // strip off everything before = to get original string
let cm = stroriginal // string to search
where cm.Equals(cc)
select mf);
nvcr_slug could be
mazhar-kaunain-baig-3-4
mazhar-kaunain-baig-3-4/mazhar-kaunain-baig-3-4
mazhar-kaunain-baig-3-4/mazhar-kaunain-baig-3-4/mazhar-kaunain-baig
abc
abc/abc
abc/abc/abc

UPDATE:
Based on your comment - I think this should work:
let b = Regex.Replace(a, #".$", '=')
In each iteration over the collection with LINQ you are dealing with just one value - the above should capture the last character in the given string and replace it with =
The first thing that I can think of is a conflict between LINQ and System.String implementations of the method Contains on:
b.Contains('=')
Try using System.String.Contains explicitly.

Use
let cc = (b.Contains("=") ? b.Substring(0, b.IndexOf("=")) : b)
and try.

Related

CodeQL "otherwise"-ish construct?

I'm new to CodeQL, and still trying to wrap my head around it. On a semi-frequent basis, I find myself wanting for a language construct that supports specifying a "fallback value", to implement the following logic:
foot Foo(...) {
result = A
or
not eists(foot t | t = A) and
result = B
or
not eists(foot t | t = A) and
not eists(foot t | t = B) and
result = C
}
// aka
foot Foo(...) {
if eists(foot t | t = A) then
result = A
else if eists(foot t | t = B) then
result = B
else
result = C
}
Does CodeQL provide a way to rephrase this in a more elegant way? I've browsed the docs over and over again for something like the following, but to no avail:
foot Foo(...) {
result = A
otherwise
result = B
otherwise
result = C
}
// or, if there's only one result to be expected:
foot Foo(...) {
result = first([ A, B, C ])
}
I feel like my little imperative programmer's brain must be missing something that's been staring at my face the whole time.
At the moment there does not seem to be such language construct. There are however discussions for requesting this (or similar) features (#5348, #5573).
Note that in your example code you could simplify your exists(foot t | t = A) to just exists(A).

Why to add 0 while using nextInt()

I am following an instructor creating tic tac toy game, to make it autoplay.
var r = Random()
val randInt = r.nextInt(emptyCell.size-0) + 0 // adding 0 here
why do we need to add +0 here?
There's no reason why you'd have to write down + 0 in that case. nextInt returns an Int, so adding 0 as an Int to it does absolutely nothing - doesn't change the type or affect the value - as you'd expect.
Probably a typo in the tutorial.
It's a billet for changing a value if you wish to. Author just showed you where and how to put it to.
Here's how your code should look like:
var random = Random()
var randomIndex: Int?
randomIndex = random.nextInt(emptyCell.size - 1) + 2 // two values instead of 00
println("randomIndex $randomIndex")
val emptyCellId = emptyCell[randomIndex]
println("emptyCellId $emptyCellId")
var btnSelect: Button?
btnSelect = setButtonId(noOfCards, emptyCellId)
Adding 0 will work but it does not change anything.
Note that you are using Java's java.util.Random which would limit your code to the JVM.
If you use kotlin.random.Random your code will target all platforms that Kotlin does and would be simpler because you don't need to instantiate a class.
You can use it like this:
val randInt = Random.nextInt(emptyCell.size)
Check out the other variants of nextInt if you don't need to specify bonds or you need to specify an upper bound.

Java 8 Streams for String manipulation

I want to perform multiple tasks on a single string.
I need to get a string and extract different sub-strings using a delimiter ("/"), then reverse the list of sub-strings and finally join them using another delimiter (".") such that /tmp/test/hello/world/ would turn into: world.hello.test.tmp
Using Java 7 the code is as follows:
String str ="/tmp/test/";
List<String> elephantList = new ArrayList<String>(Arrays.asList(str.split("/")));
StringBuilder sb = new StringBuilder();
for (int i=elephantList.size()-1; i>-1; i--) {
String a = elephantList.get(i);
if (a.equals(""))
{
elephantList.remove(i);
}
else
{
sb.append(a);
sb.append('.');
}
}
sb.setLength(sb.length() - 1);
System.out.println("result" + elephantList + " " + sb.toString());
I was wondering how I could do the same thing using Java 8 streams and the join function it has for Strings
The most straightforward way is to collect the terms into a list, reverse the list and join on the new delimiter:
import static java.util.stream.Collectors.toCollection;
List<String> terms = Pattern.compile("/")
.splitAsStream(str)
.filter(s -> !s.isEmpty())
.collect(toCollection(ArrayList::new));
Collections.reverse(terms);
String result = String.join(".", terms);
You can do it without collecting into an intermediate list but it will be less readable and not worth the trouble for practical purposes.
Another issue to consider is that your strings appear to be paths. It is usually better to use Path class rather than splitting by "/" manually. Here's how you would do this (this approach also demonstrates how to use IntStream over indexes to stream over a list backwards):
Path p = Paths.get(str);
result = IntStream.rangeClosed(1, p.getNameCount())
.map(i -> p.getNameCount() - i) // becomes a stream of count-1 to 0
.mapToObj(p::getName)
.map(Path::toString)
.collect(joining("."));
This will have the advantage of being OS-independent.
If you do not want an intermediate list and just want to join the String reversely:
String delimiter = ".";
Optional<String> result = Pattern.compile("/")
.splitAsStream(str)
.filter(s -> ! s.isEmpty())
.reduce((s, s2) -> String.join(delimiter, s2, s));
Or just use .reduce((s1, s2) -> s2 + '.' + s1); as it is probably as readable as String.join(".", s2, s1); (thanks Holger for the suggestion).
From then on you could do one of the following:
result.ifPresent(System.out::println); // print the result
String resultAsString = result.orElse(""); // get the value or default to empty string
resultAsString = result.orElseThrow(() -> new RuntimeException("not a valid path?")); // get the value or throw an exception
Another way using StreamSupport and Spliterator (inspired by Mishas suggestion to use a Path):
Optional<String> result = StreamSupport.stream(Paths.get(str).spliterator(), false)
.map(Path::getFileName)
.map(Path::toString)
.reduce((s, s2) -> s2 + '.' + s);
Of course you can simplify it by omitting the intermediate Optional-object and just call your desired method immediately:
stream(get(str).spliterator(), false)
.map(Path::getFileName)
.map(Path::toString)
.reduce((s, s2) -> s2 + '.' + s)
.ifPresent(out::println); // orElse... orElseThrow
in the last example you would add the following static imports:
import static java.lang.System.out;
import static java.nio.file.Paths.get;
import static java.util.stream.StreamSupport.stream;
Your Java 7 code isn’t what I’d call a straight-forward solution.
This is, how I would implement it in Java 7:
String str = "/tmp/test/";
StringBuilder sb = new StringBuilder(str.length()+1);
for(int s=str.lastIndexOf('/'), e=str.length(); e>=0; e=s, s=str.lastIndexOf('/', e-1)) {
if(s+1<e) sb.append(str, s+1, e).append('.');
}
if(sb.length()>0) sb.setLength(sb.length() - 1);
System.out.println("result " + sb);
and thinking about it again, this is also how I’d implement it in Java 8, as using the Stream API doesn’t really improve this operation.
You can write like this :
String newPath = Arrays.asList(path.split("/")).stream()
.filter(x -> !x.isEmpty())
.reduce("",(cc,ss)->{
if(!cc.isEmpty())
return ss+"."+cc;
else return ss;
},(s1,s2)->s2+s1);
The filter eliminates first backslash and reduce method has to control if there are any other last empty strings.

F# record and evaluating of this

I'm struggling a bit with a F#-assignment, which I hope you can answer for mere: I have that
We will use the type OrderedList<’a> declared as follows
type OrderedList<’a when ’a : equality> =
{ front: ’a list
; rear: ’a list}
For instance, the value let ex = {front = [’x’]; rear = [’z’;’y’]} has
type OrderedList<char> and represents the ordered list [’x’, ’y’, ’z’].
The question that I'm struggling with is:
We define the canonical representation of an ordered list to be the
representation where the rear list is empty. Declare a function
canonical:OrderedList<’a>->OrderedList<’a>, where canonical ol returns
the canonical representation of ol.
Just as a startup, I've tried something:
let canonicial (list:OrderedList<'a>)=
match list with
| {x::xs}, {y::xss} -> if x = y then "SUCCESS!!!!" else failwith "FEJL!!!"
| _ -> failwith "Some"
My issue is that I don't know how to get to the element in the type / the syntax for this. I know the function has not been solved correctly, but right now I focus mostly on the syntax.
Hope to get some help!
Well I think I can give you the solution now (you surely have more problems to solve):
let canonical =
function
| { front = _; rear = [] } as ol -> ol
| { front = fs; rear = rs } -> { front = fs # List.rev rs; rear = [] }
as you can see the first case is when the rear is already empty - here it's enough to give to original back
in the other case we have to get a new OrderedList<'a> with the reversed old rear appended to the old front - that's it - you don't even need the constraint on 'a - and indeed I find it strange to put it there - usually it's better to but the constraints on the functions in FP - but well different styles and stuff.
I hope this helps you out a bit
BTW: I used function on purpose - you should try to convert this into your usual match ... with ... style so you can get your syntax right
Thanks, thanks, thanks! Now I better understand this topic! I rewritten your code to:
let canonical2 (ol:OrderedList<'a>) : OrderedList<'a> =
match ol with
|{ front = _; rear = []} -> ol
|{ front = f; rear = r} -> {front = f # List.rev r; rear = []}
Another way to do it granted that # already takes care of returning the "other list" if one is empty (so shouldn't be an overhead to always append) :
let canonical ol = { ol with front = ol.front # List.rev ol.rear; rear = [] }
// or
let canonical { front = fs; rear = rs } = { front = fs # List.rev rs; rear = [] }

A simple linq query to start the day

I have a class that contains a ints, string and pointers to other classes. I'm trying to extract the strings and perform a substring operation on them before I select.Distinct. My LINQ code looks right
List<string> crops = (from m in cropTypes
let cw = m.CropName
let kw = cw.Substring(0, cw.LastIndexOf(")") + 1)
select(kw).Distinct()).ToList();
I have also tried
var crop = …
List<string> crops = crop.ToList();
When I attempt to compile, I'm getting
Cannot implicitly convert type
System.Collections.Generic.List<System.Collections.Generic.IEnumerable<char>> to System.Collections.Generic.List<System.Collections.Generic.IEnumerable<string>>
on the ToList() line.
m.CropName is definitely a string
Why does the compiler think that I'm using a char list rather than a string list and how do I fix this.
Nothing like a simple problem to stump you at the start of a day!
try
List<string> crops = (from m in cropTypes
let cw = m.CropName
let kw = cw.Substring(0, cw.LastIndexOf(")") + 1)
select kw).Distinct().ToList();
If you call Distinct on a string, you're actually enumerating the string's characters.

Resources