So I have a giant pipe in my cascade that looks like this:
K1 - V1
K1 - V2
K1 -V3
K2 - V4
K2- V5
K2-V6
Is there anyway to aggregate them using an Every pipe such that the output looks something along these lines:
K1 - {V1, V2, V3}
K2 - {V4, V5, V6}
Thank you!
Edit:
My code so far:
I am calling the Every Pipe
OutputPipe = new Every(OutputPipe, Fields.ALL, SomeBuffer());
And I am overriding the operate method in the buffer:
#Override
public void operate( FlowProcess flowProcess, BufferCall bufferCall )
{
TupleEntry group = bufferCall.getGroup();
// get all the current argument values for this grouping
Iterator<TupleEntry> arguments = bufferCall.getArgumentsIterator();
// create a Tuple to hold our result values
String result = "";
String key = "";
if (arguments.hasNext()) {
TupleEntry argument = arguments.next();
key = argument.getString("key") + "\t";
}
while (arguments.hasNext()) {
TupleEntry argument = arguments.next();
result += argument.getString("value") + "\t";
}
bufferCall.getOutputCollector().add(new Tuple(key, result));
}
The output I get is kind of strange though. I keep getting strange results from reading in the file, so I'm guessing my logic in the every pipe is wrong.
Related
Question :
from the list of an integer get the square of odd number and half the even number and then return the list of value.
Ans : 1> i will write the logic and if else condition inside the map() method.
List<Integer> output = intArray.stream().map(x-> {
if(x%2 ==0){
x=x/2;
}else{
x= x*x;
}
}).collect(Collectors.toList());
Is their any better way to do this specially using Filter?
Try using map:
map(x -> x % 2 == 0? x / 2: x * x);
Let me know if this works for you.
You can learn more about map and filter here
As you are transforming data (performing a math operation), you cannot use Filter here. Filter is used to filter out elements in your stream. For example if you only want to preserve the even numbers, you could use a Filter
What you need to use is the Map, as you already did. Do note that a map should always return data. Your code is missing this return statement.
To make it more readable, you could split your mapping logic in a method. This makes your stream easy to read and easy to follow (when you give the method a good name ofcourse).
Code example
List<Integer> output = intArray.stream()
.map(test::divideOrPow)
.collect(Collectors.toList());
private int divideOrPow(intx) {
if (x % 2 == 0) {
return x / 2;
} else {
return x * x;
}
}
I have tried to use say-as interpret-as to make Alexa speak number in digits
Example - 9822 must not read in words instead '9,8,2,2'
One of the two ways I have tried is as follows:
this.emit(':tell',"Hi "+clientname+" your "+theIntentConfirmationStatus+" ticket is sent to "+ "<say-as interpret-as='digits'>" + clientno + "</say-as>",'backup');
The other one is this:
this.response.speak("Hi "+clientname+" your "+theIntentConfirmationStatus+" ticket is sent to "+ "<say-as interpret-as='digits'>" + clientno + "</say-as>");
Both are not working but working on a separate fresh function.
Actually your code SHOULD work.
Maybe you can try in test simulator and send us the code your script produces? Or the logs?
I've tried the following:
<speak>
1. The numbers are: <say-as interpret-as="digits">5498</say-as>.
2. The numbers are: <say-as interpret-as="spell-out">5498</say-as>.
3. The numbers are: <say-as interpret-as="characters">5498</say-as>.
4. The numbers are: <prosody rate="x-slow"><say-as interpret-as="digits">5498</say-as></prosody>.
5. The number is: 5498.
</speak>
Digits, Spell-out and Characters all have the effect you want.
If you want to Alexa to say it extra slow, use the prosody in #4.
Try using examples #2 or #3, maybe this works out?
Otherwise the example from Amod will work too.
You can split number into individual digits using sample function ( please test it for your possible inputs-its not tested for all input). You can search for similar function on stackoverflow
function getNumber(tablenumber) {
var number = (""+tablenumber).split("");
var arrayLength = number.length;
var tmp =" ";
for (var i = 0; i < arrayLength; i++) {
var tmp = tmp + myStringArray[i] + ", <break time=\"0.4s\"/> ";
}
return tmp;
}
In your main function... call this
var finalresult = getNumber(clientno);
this.emit(':tell',"Hi "+clientname+" your "+theIntentConfirmationStatus+" ticket is sent to "+ finalresult ,'backup');
Edited: Yep, nightflash's answer is great.
You could also break the numbers up yourself if you need other formatting, such as emphasizing particular digits, add pauses, etc. You would need to use your Lambda code to convert the numeric string to multiple digits separated by spaces and any other formatting you need.
Here's an example based on the answers in this post:
var inputNumber = 12354987;
var output = '';
var sNumber = inputNumber.toString();
for (var i = 0, len = sNumber.length; i < len; i += 1) {
// just adding spaces here, but could be SSML attributes, etc.
output = output + sNumber.charAt(i) + ' ';
}
console.log(output);
This code could be refactored and done many other ways, but I think this is about the easiest to understand.
hello guys i am new to maps in C++ i am having a question regarding copying a particular type map to another map of same kind the details are shown below
I initially declared a map like this
map<string,int> objmap,obj_porcess ;
for(int i = 0; i < 10]; i++) {
obj_process[to_string(i)]=i+10//some processing the to_string is just in case but i have strings with names for all 10 values
}
like
obj_process["today"]=1;
obj_process["yesterday"]=-1;
obj_process["tommorow"]=2;
now i want to define some thing like this just my key word should be added with the process and remaining all can be same for all the keys from obj_process
objmap["process_"+"today"] = obj_process["today"];
instead of defining all 10 can i have a simple code cause in here i took an example of 10 but i have like 200 set of different strings in the key of map
I think this is what you need:
map<string,int> objmap;
map<string,int> obj_porcess;
//
// Fill up the contents of obj_porcess
//
// Copy objects from obj_porcess to objmap using a computed key.
for ( auto& item : obj_process )
{
objmap[std::string("process_") + item.first] = item.second;
}
Could you iterate over the map?
for(auto &i : obj_process)
objmap["process" + i.first] = i.second;
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.
List<String> checkLength(List<String> input) {
if (input.length > 6) {
var tempOutput = input;
while (tempOutput.length > 6) {
var difference = (tempOutput.length/6).round() + 1;
for (int i = 0; i < tempOutput.length - 1; i + difference) {
tempOutput.removeAt(i); //Removing the value from the list
}
}
return tempOutput; //Return Updated list
} else {
return input;
}
}
I am trying to delete something out of a temporary list. Why does it not work? I do not see how it is fixed, in other problems I have solved, I used a similar approach and it worked (Even identical nearly)
Please note I am kind of new to Dart, so please forgive me this sort of question, but I couldn't figure out the solution.
Find the Code available in the Dart Link
Code in Dart
You can ensure that tempOutput is not a fixed-length list by initializing it as
var tempOutput = new List<String>.from(input);
thereby declaring tempOutput to be a mutable copy of input.
FYI it also looks like you have another bug in your program since you are doing i + difference in your for-loop update step but I think you want i += difference.
Can you please try this code and let me know is that works?
List<String> checkLength(List<String> input) {
if (input.length > 6) {
var tempOutput = input;
while (tempOutput.length > 6) {
var difference = (tempOutput.length/6).round() + 1;
for (int i = 0; i < tempOutput.length - 1; i = i + difference) {
tempOutput.removeAt(i); //Removing the value from the list
}
}
return tempOutput.toList(); //Return Updated list
} else {
return input.toList();
}
}
Note: You used "i + difference" which is same value say for example in first iteration you i=1 and difference = 1, then "tempOutput.removeAt(i)" will remove the value at "1" position, again in the second iteration you are trying to remove the same position, so the error clearly states "Cannot remove from the Fixed length"
Here the i value has to be incremented or decremented for each iteration process, in your for loop that is missing.
The answer of #harry-terkelsen was very helpful for solving the fixed-length problem.
For those who were asking about my algorithm:
The difference is for skipping the amount of characters when wanting to remove some. Also, I had to change the for-loop, as it did not quite do what I wanted it to.
The fix is here! https://github.com/luki/wordtocolor/blob/master/web/algorithms.dart
Thank you for understanding me!