Buffer with other publisher - Spring reactor - spring

Can anyone give an example of how Flux.buffer(Publisher other) works, im unable to make use of the other publisher to split the original flux into multiple lists.
Ex:
List<String> strings = new ArrayList<>();
strings.add("A");
strings.add("B");
Flux<String> stringFlux = Flux.fromIterable(strings).cache();
for(int i = 0; i < 100; i++) {
strings.add(""+i);
}
List<Integer> integers = new ArrayList<>(2);
integers.add(1);
integers.add(1);
integers.add(1);
stringFlux.buffer((a) -> {
Flux.fromIterable(integers);
}).subscribe(a -> {
System.out.println(a);
});
this still prints the original list as the output rather than split it.

bufferuntil with a predicate is actually what i was looking for.

Related

C# coding, I need to create several text files and populate it with unsorted lists of integers, then read it from the respective file into a list

ArrayList List;
String FileName;
static void Main(string[] args)
{
List<int> Integers = new List<int>();
Console.WriteLine("Please pick desired list size");
Console.WriteLine("Use the respective number (1)Small, (2)Medium, (3)Large, or (4)XLarge");
int size = int.Parse(Console.ReadLine());
Randomgen(List);
}
static void Randomgen(int Size, ArrayList List)
{
StreamWriter SW = new StreamWriter(FileName); ;
switch (Size)
{
case 1:
Random random = new Random();
for (int i = 0; i < 101; i++)
{
List.Add(new Integers(random.Next(1, int.MaxValue)));
}
break;
case 2:
Random randomM = new Random();
for (int i = 0; i < 2001; i++)
{
List.Add(new Integers(randomM.Next(1, int.MaxValue)));
}
break;
case 3:
Random randomL = new Random();
for (int i = 0; i < 20001; i++)
{
List.Add(new Integers(randomL.Next(1, int.MaxValue)));
}
break;
case 4:
Random randomXL = new Random();
for (int i = 0; i < 200001; i++)
{
List.Add(new Integers(randomXL.Next(1, int.MaxValue)));
}
break;
}
}
static void populateListFromFile(string FileName, ArrayList List)
{
StreamReader Input = new StreamReader(FileName);
while (!Input.EndOfStream)
{
List.Add(new Integers(int.Parse(Input.ReadLine())));
}
Console.WriteLine("File has been successfully imported");
}
}
****Im trying to create 1 of 4 different text files based of the user selection using the switch case, with an arraylist of unsorted integers and then I want to Streamread back into an arraylist usign my populate listfrom file method, so that I may proceed to sort them later using 3 other sorting methods. the whole point is to measure the efficiency of the algorithms over different amounts of data or list sizes. the main method is giving me trouble though. Most of my knowledge is self studied so please bare with me.
So what exactly is the problem you are facing, from what I can see, your Randomgen function accepts 2 parameters which is int Size and ArrayList List. However in your call to it in Main you are only providing it with 1 parameters Randomgen(List);, therefore the whole switch case inside of that function won't work.

Is there a way to avoid the truncation of attached properties when using Appcenter with Xamarin?

Here's my code:
Crashes.TrackError(ex,
new Dictionary<string, string> {
{"RunQuery", "Exception"},
{"sql", s },
{"Device Model", DeviceInfo.Model },
{"Exception", ex.ToString()}
});
Everything works but I find that Appcenter limits the length of the parameters to 125 characters so it's useless for me as I can never see all of the sql or the ex string.
Has anyone found a way to get around this?
I ran into the same problem. My solution was to break my string into groups of 125 character strings and iterate through while logging. I chatted with AppCenter support. They have no way of extending this length currently.
Here is a scrubbed version of my code:
var tokenChunks = LoggingHelper.SplitBy(extremelyLongString, 120);
string title = "Long string here";
var props = new Dictionary<string, string>();
int item = 0;
foreach(string chunk in tokenChunks)
{
string chunkIndex = string.Format("item: {0}", item++);
props.Add(chunkIndex, chunk);
}
Analytics.TrackEvent(title, props);
Where the LoggingHelper class is:
public static class LoggingHelper
{
public static IEnumerable<string> SplitBy(this string str, int chunkLength)
{
if (String.IsNullOrEmpty(str)) throw new ArgumentException();
if (chunkLength < 1) throw new ArgumentException();
for (int i = 0; i < str.Length; i += chunkLength)
{
if (chunkLength + i > str.Length)
chunkLength = str.Length - i;
yield return str.Substring(i, chunkLength);
}
}
}
I should give credit to this post https://stackoverflow.com/a/8944374/117995 by #oleksii for the SplitBy method.

Map first element of stream differently than rest

Is there a way in Java's Stream API to map first element of stream differently than other?
Equivalent of this code:
List<Bar> barList = new ArrayList<>();
for (int i=0; i<fooList.size(); i++) {
Foo foo = fooList.get(i);
Foo modifiedFoo = foo.getModifiedFoo();
if (i == 0) {
barList.add(new Bar(modifiedFoo, false));
}else {
barList.add(new Bar(modifiedFoo, true));
}
}
Stream<Bar> = barList.stream();
Note: I already have a stream setup and I would want some operation after first mapping
fooList.stream()
.map(Foo::getModifiedFoo)
.(May be Some operation here to get different new Bar for first modifiedFoo)
.map(modifiedFoo -> new Bar(modifiedFoo, true));
I would get the first element, create a Stream out of it and apply the needed mappings. Then, I'd take the rest of the list, create a stream out of it and apply the different mappings. Then concat the streams. Something like this:
Stream<Bar> first = Stream.of(fooList.get(0))
.map(Foo::getModifiedFoo)
.map(modifiedFoo -> new Bar(modifiedFoo, false));
Stream<Bar> others = fooList.subList(1, fooList.size()).stream()
.map(Foo::getModifiedFoo)
.map(modifiedFoo -> new Bar(modifiedFoo, true));
Stream<Bar> bars = Stream.concat(first, others).flatMap(s -> s);
Another approach:
Stream<Bar> bars = IntStream.range(0, fooList.size())
.mapToObj(i -> new Bar(fooList.get(i).getModifiedFoo(), i > 0));
This way is succinct and does the job pretty well.
Use an IntStream to iterate over the indices, then mapToObj to create an object for that index, and finally collect into a list:
List<Bar> barList = IntStream.range(0, fooList.size())
.mapToObj(i -> (i == 0 ? new Bar (fooList.get(i), false) :
new Bar(fooList.get(i),true)))
.collect(Collectors.toList());
What would be more readable though, is doing the first item handling outside the loop, and using IntStream starting with 1.
Here is a demo using simple lists.
I can propose two ways but I find your way straighter.
With IntStream such as :
List<Bar> barList = new ArrayList<>();
IntStream.range(0, fooList.size())
.forEach(i->{
if (i == 0) {
barList.add(new Bar(foo, false));
}else {
barList.add(new Bar(foo, true));
}
}
);
It is not a real functional approach (forEach() use and no Collector) because it maintains the current index of the List.
As alternative, you could use a more functional approach but I don't find it straighter either :
List<Bar> barList = IntStream.range(0, fooList.size())
.mapToObj(i->{
Foo foo = fooList.get(i);
if (i == 0) {
return new Bar(foo, false);
}
return new Bar(foo, true));
})
.collect(Collectors.toList());
Although I think the accepted answer is better, here is an alternate approach.
int[] counter = {-1};
Stream<Bar> barListStream = fooList.stream().map(foo -> {
counter[0]++;
return new Bar(mfoo.getModifiedFoo(), counter[0]>0);
}).collect(Collectors.toList()).stream();
You can have an object to hold a flag e.g. AtomicBoolean or AtomicInteger - that you can reset on first or nth iteration (you would need something like AtomicInteger or some Integer holder to reset on nth iteration) e.g. following code using HashMap as the holder class - will print first line of the stream differently than the other lines:
Map<String, Boolean> firstTime = new HashMap<>(Map.of("firstTime", true)); // to make the map modifiable
try (Stream<String> lines = Files.lines(Paths.get(filename), Charset.defaultCharset())) {
lines.forEachOrdered(line -> System.out.println(firstTime.remove("firstTime") != null ? ("firstTime: " + line) : line));
}
Use an AtomicBoolean initially set to true to determine when is the first item.
final AtomicBoolean first = new AtomicBoolean(true);
System.out.println("** Print all numbers 1..10");
IntStream.range(1, 11).forEach(number -> {
System.out.print((first.get() ? "" : ",") + number);
first.set(false);
});
System.out.println();

Dynamically choose which properties to get using Linq

I have an MVC application with a dynamic table on one of the pages, which the users defines how many columns the table has, the columns order and where to get the data from for each field.
I have written some very bad code in order to keep it dynamic and now I would like it to be more efficient.
My problem is that I don't know how to define the columns I should get back into my IEnumerable on runtime. My main issue is that I don't know how many columns I might have.
I have a reference to a class which gets the field's text. I also have a dictionary of each field's order with the exact property It should get the data from.
My code should look something like that:
var docsRes3 = from d in docs
select new[]
{
for (int i=0; i<numOfCols; i++)
{
gen.getFieldText(d, res.FieldSourceDic[i]);
}
};
where:
docs = List from which I would like to get only specific fields
res.FieldSourceDic = Dictionary in which the key is the order of the column and the value is the property
gen.getFieldText = The function which gets the entity and the property and returns the value
Obviously, it doesn't work.
I also tried
StringBuilder fieldsSB = new StringBuilder();
for (int i = 0; i < numOfCols; i++)
{
string field = "d." + res.FieldSourceDic[i] + ".ToString()";
if (!string.IsNullOrEmpty(fieldsSB.ToString()))
{
fieldsSB.Append(",");
}
fieldsSB.Append(field);
}
var docsRes2 = from d in docs
select new[] { fieldsSB.ToString() };
It also didn't work.
The only thing that worked for me so far was:
List<string[]> docsRes = new List<string[]>();
foreach (NewOriginDocumentManagment d in docs)
{
string[] row = new string[numOfCols];
for (int i = 0; i < numOfCols; i++)
{
row[i] = gen.getFieldText(d, res.FieldSourceDic[i]);
}
docsRes.Add(row);
}
Any idea how can I pass the linq the list of fields and it'll cut the needed data out of it efficiently?
Thanks, Hoe I was clear about what I need....
Try following:
var docsRes3 = from d in docs
select (
from k in res.FieldSourceDic.Keys.Take(numOfCols)
select gen.getFieldText(d, res.FieldSourceDic[k]));
I got my answer with some help from the following link:
http://www.codeproject.com/Questions/141367/Dynamic-Columns-from-List-using-LINQ
First I created a string array of all properties:
//Creats a string of all properties as defined in the XML
//Columns order must be started at 0. No skips are allowed
StringBuilder fieldsSB = new StringBuilder();
for (int i = 0; i < numOfCols; i++)
{
string field = res.FieldSourceDic[i];
if (!string.IsNullOrEmpty(fieldsSB.ToString()))
{
fieldsSB.Append(",");
}
fieldsSB.Append(field);
}
var cols = fieldsSB.ToString().Split(',');
//Gets the data for each row dynamically
var docsRes = docs.Select(d => GetProps(d, cols));
than I created the GetProps function, which is using my own function as described in the question:
private static dynamic GetProps(object d, IEnumerable<string> props)
{
if (d == null)
{
return null;
}
DynamicGridGenerator gen = new DynamicGridGenerator();
List<string> res = new List<string>();
foreach (var p in props)
{
res.Add(gen.getFieldText(d, p));
}
return res;
}

Adding dynamic values in an input box using watin for a web based application

I am working on a web based application which takes care of online orders placed by customers .
we are using watin for sanity.This is what my code reads
mybrowser.TextField(Find.ByName("searchBox")).Value = "milk";
mybrowser.Image(Find.ByName("search")).Click();
In the input field i want to add any string value(e.g meat/bakery) of X length
Please help
As I read your question you want to be able to generate and input a string of a specific, given length X. Here is some code I wrote a while ago for that.
public static string GetRandomString(int length)
{
StringBuilder randomString = new StringBuilder();
Random randomNumber = new Random();
for (int i = 0; i < length; i++)
{
randomString.Append(Convert.ToChar(Convert.ToInt32(Math.Floor(26 * randomNumber.NextDouble() + 65))));
}
return randomString.ToString();
}
If you want to pick from a specific list of items I would use code like this
public static string GenerateRandomFood()
{
string[] foods = {"Bread", "Cheese", "Milk", };
// There are 3 food names
return foods[GetRandomInt(0, 2)];
}
Hope that is what you are after.

Resources