问:
Firebase Data Collection with Unique Member
I would like to show a list of toys.
ach toy as a unique name.
The name can contain any character, so it can have a dot a slash or a dollar.
This is why I would prefer to use the push method to get a generated key.

The code I end up with is troublesome.
It is not thread safe and I could end up with duplicate toys.
Is there a better way?

```<code>var child = testsRef.orderByChild("name").equalTo("Meccano");

return child.once('value').then(function(snapshot) {
  var snap = snapshot.val();
  if (snapshot.val()) {
    alert('Toy ' + value + ' already exists.');
  } else {
    var newPostKey = testsRef.push().key;
    var updates = {};
    updates[newPostKey] = {          name: value        };
    var result = testsRef.update(updates);
    alert('We can only assume that it has worked.' + result);
  }
});
</code>```

I built a complete working codepen to illustrate my question here:
http://codepen.io/paganaye/pen/EWrayY

答:
This is an alternative solution using Unicode characters.
For example the # character is replaced by a very similarequals sign and slanted parallel : '⧣'.

var nameElt = document.getElementById("name");
var sanitizedElt = document.getElementById("sanitized");
var sanitized2Elt = document.getElementById("sanitized2");
var decodedElt = document.getElementById("decoded");
var outpuElt = document.getElementById("output");
var decoded2Elt = document.getElementById("decoded2");

function fbKeySanitizer(str) {
  return str.replace(/[%.$[\]#\/]/g, function (c) {
    return '%' + c.charCodeAt(0).toString(16).toUpperCase();
  });
}

var unicodeReplacements = {
  '.':'․', // One dot leader
  '$':'ᙚ', // Canadian syllabics carrier: sh
  '[':'⟦', // Mathematical left white square bracket
  ']':'⟧', // Mathematical right white square bracket
  '#':'⧣', // Equals sign and slanted parallel
  '/':'⧸' // big solidus
}
var decodeUnicodeReplacements = {};
for (var prop in unicodeReplacements) {
  decodeUnicodeReplacements[unicodeReplacements[prop]]=prop;
}

function fbKeySanitizer2(str) {
  return str.replace(/[.$[\]#\/]/g, function (c) {
    return unicodeReplacements[c];
  });
}

function fbDecoded2(str) {
  return str.replace(/[․ᙚ⟦⟧⧣⧸]/g, function (c) {
    return decodeUnicodeReplacements[c];
  });
}

function nameKeyUp() {
  var sanitized1string = fbKeySanitizer(nameElt.value);
  sanitizedElt.innerText = sanitized1string;
  decodedElt.innerText =  decodeURIComponent(sanitized1string);

  var sanitized2string = fbKeySanitizer2(nameElt.value);
  sanitized2Elt.innerText = sanitized2string;
  decoded2Elt.innerText =  fbDecoded2(sanitized2string);
}
nameKeyUp();```
<pre class="snippet-code-html lang-html prettyprint-override"><code><script src="https://www.gstatic.com/firebasejs/3.6.1/firebase.js"></script>
<form>
  <h1>Firebase invalid key characters escaping</h1>
  <label for="name">name:</label>
  <input id="name" onkeyup="nameKeyUp()" value="A%.B[#0]/x" />
  <hr>
  <form>
  <h3>Method One</h3>
  <p>Sanitized1: <span id="sanitized"></span></p>
  <p>Decoded1: <span id="decoded"></span></p>
  <hr>
  <h3>Method Two</h3>
  <p>Sanitized2: <span id="sanitized2"></span></p>
  <p>Decoded2: <span id="decoded2"></span></p>
</form></code>```

Body:
I would like to show a list of toys.
ach toy as a unique name.
The name can contain any character, so it can have a dot a slash or a dollar.
This is why I would prefer to use the push method to get a generated key.

The code I end up with is troublesome.
It is not thread safe and I could end up with duplicate toys.
Is there a better way?

var child = testsRef.orderByChild("name").equalTo("Meccano");

return child.once('value').then(function(snapshot) {
  var snap = snapshot.val();
  if (snapshot.val()) {
    alert('Toy ' + value + ' already exists.');
  } else {
    var newPostKey = testsRef.push().key;
    var updates = {};
    updates[newPostKey] = {          name: value        };
    var result = testsRef.update(updates);
    alert('We can only assume that it has worked.' + result);
  }
});

I built a complete working codepen to illustrate my question here:
http://codepen.io/paganaye/pen/EWrayY

Body:
This is an alternative solution using Unicode characters.
For example the # character is replaced by a very similarequals sign and slanted parallel : '⧣'.

var nameElt = document.getElementById("name");
var sanitizedElt = document.getElementById("sanitized");
var sanitized2Elt = document.getElementById("sanitized2");
var decodedElt = document.getElementById("decoded");
var outpuElt = document.getElementById("output");
var decoded2Elt = document.getElementById("decoded2");

function fbKeySanitizer(str) {
  return str.replace(/[%.$[\]#\/]/g, function (c) {
    return '%' + c.charCodeAt(0).toString(16).toUpperCase();
  });
}

var unicodeReplacements = {
  '.':'․', // One dot leader
  '$':'ᙚ', // Canadian syllabics carrier: sh
  '[':'⟦', // Mathematical left white square bracket
  ']':'⟧', // Mathematical right white square bracket
  '#':'⧣', // Equals sign and slanted parallel
  '/':'⧸' // big solidus
}
var decodeUnicodeReplacements = {};
for (var prop in unicodeReplacements) {
  decodeUnicodeReplacements[unicodeReplacements[prop]]=prop;
}

function fbKeySanitizer2(str) {
  return str.replace(/[.$[\]#\/]/g, function (c) {
    return unicodeReplacements[c];
  });
}

function fbDecoded2(str) {
  return str.replace(/[․ᙚ⟦⟧⧣⧸]/g, function (c) {
    return decodeUnicodeReplacements[c];
  });
}

function nameKeyUp() {
  var sanitized1string = fbKeySanitizer(nameElt.value);
  sanitizedElt.innerText = sanitized1string;
  decodedElt.innerText =  decodeURIComponent(sanitized1string);

  var sanitized2string = fbKeySanitizer2(nameElt.value);
  sanitized2Elt.innerText = sanitized2string;
  decoded2Elt.innerText =  fbDecoded2(sanitized2string);
}
nameKeyUp();

<script src="https://www.gstatic.com/firebasejs/3.6.1/firebase.js"></script>
<form>
  <h1>Firebase invalid key characters escaping</h1>
  <label for="name">name:</label>
  <input id="name" onkeyup="nameKeyUp()" value="A%.B[#0]/x" />
  <hr>
  <form>
  <h3>Method One</h3>
  <p>Sanitized1: <span id="sanitized"></span></p>
  <p>Decoded1: <span id="decoded"></span></p>
  <hr>
  <h3>Method Two</h3>
  <p>Sanitized2: <span id="sanitized2"></span></p>
  <p>Decoded2: <span id="decoded2"></span></p>
</form>


来源: stackexchange

问:
Android - shadow on text?
I am wondering how to add shadow on text in android?

I have the following code which is applied on a bitmap and I wanted to be shadowed...

```<code>paint.setColor(Color.BLACK);
paint.setTextSize(55);
paint.setFakeBoldText(false);
paint.setShadowLayer(1, 0, 0, Color.BLACK); //This only shadows my whole view...
</code>```

答:
If you want to achieve a shadow like the one that Android does in the Launcher, we're managing these values. They're useful if you want to create TextViews that will appear as a Widget, without a background.</p>

```<code>android:shadowColor="#94000000"
android:shadowDy="2"
android:shadowRadius="4"
</code>```

ContentLicense: CC BY-SA 4.0

Title: Android - shadow on text?

Body:
I am wondering how to add shadow on text in android?

I have the following code which is applied on a bitmap and I wanted to be shadowed...

paint.setColor(Color.BLACK);
paint.setTextSize(55);
paint.setFakeBoldText(false);
paint.setShadowLayer(1, 0, 0, Color.BLACK); //This only shadows my whole view...

Body:
If you want to achieve a shadow like the one that Android does in the Launcher, we're managing these values. They're useful if you want to create TextViews that will appear as a Widget, without a background.

android:shadowColor="#94000000"
android:shadowDy="2"
android:shadowRadius="4"

ContentLicense: CC BY-SA 3.0


问:
DSC Push mode - best way to copy DSC resources
I'm exploring DSC and wondering what's the best way to copy DSC resources to target host ?

When I try to push my configuration to the target host, It complain of missing DSC resource.

```<code>The PowerShell DSC resource xWebAdministration does not exist at the PowerShell module path nor is it registered as a WMI DSC resource.
    + CategoryInfo          : InvalidOperation: (root/Microsoft/...gurationManager:String) [], CimException
    + FullyQualifiedErrorId : DscResourceNotFound
    + PSComputerName        : server1.appman.net
</code>```

答:
The error comes when module is not found in PSModule paths.

Use the following line to install xWebAdministration powershell module from PSGallery repository Install-Module -Name xWebAdministration

Then click "Yes to All" when a pop up comes, the module gets installed

To crosscheck if the module got installed, type
$env:PSModulePath in powershell console and find xWebAdministration folder in PS Module paths

Body:
I'm exploring DSC and wondering what's the best way to copy DSC resources to target host ?

When I try to push my configuration to the target host, It complain of missing DSC resource.

The PowerShell DSC resource xWebAdministration does not exist at the PowerShell module path nor is it registered as a WMI DSC resource.
    + CategoryInfo          : InvalidOperation: (root/Microsoft/...gurationManager:String) [], CimException
    + FullyQualifiedErrorId : DscResourceNotFound
    + PSComputerName        : server1.appman.net


问:
How to use visual controls in Indy? (Delphi)
My server must print some reports about its work. How can I use visual objects such as labels, edit boxes in the OneEecute event?</p>

答:
The same rule, for not modifying VCL objects in any thread except main thread, is valid here too. You should not change any of VCL controls in OnExecute event-handler, because that code will be run in the context of a worker thread spawn by Indy for every connection.

If you need to change graphical user interface, do it using Synchronize or Queue methods, or use a custom notification mechanism for notifying the main thread to do the GUI modification for you.

If you want to call Synchronize or Queue methods, you have to type-cast TIdYarn to TIdYarnOfThread which derives from TIdYarn and implements it with threads:

```<code>// Calling MyMethod using Synchornize inside TIdTcpServer.OnExecute event-handler
TIdYarnOfThread(AContext.Yarn).Thread.Synchronize(MyMethod);

// Calling MyMethod using Queue inside TIdTcpServer.OnExecute event-handler
TIdYarnOfThread(AContext.Yarn).Thread.Queue(MyMethod);
</code>```

ContentLicense: CC BY-SA 2.5

Body:
The same rule, for not modifying VCL objects in any thread except main thread, is valid here too. You should not change any of VCL controls in OnExecute event-handler, because that code will be run in the context of a worker thread spawn by Indy for every connection.

If you need to change graphical user interface, do it using Synchronize or Queue methods, or use a custom notification mechanism for notifying the main thread to do the GUI modification for you.

If you want to call Synchronize or Queue methods, you have to type-cast TIdYarn to TIdYarnOfThread which derives from TIdYarn and implements it with threads:

// Calling MyMethod using Synchornize inside TIdTcpServer.OnExecute event-handler
TIdYarnOfThread(AContext.Yarn).Thread.Synchronize(MyMethod);

// Calling MyMethod using Queue inside TIdTcpServer.OnExecute event-handler
TIdYarnOfThread(AContext.Yarn).Thread.Queue(MyMethod);


问:
Disabling flash in Chrome
One of our internal applications has a flash object on a page. I need to test one of the corner cases when there is no flash plugin available/installed in the browser: neither the internal (pepperflash), nor the system-wide adobe flash player plugin.

According to the List of Chromium Command Line Switches documentation page, there is a relevant command-line switch:

--disable-bundled-ppapi-flash - Disables the bundled PPAPI version of Flash.

But, this would turn off only the pepperflash internal chrome plugin.

According to the How to run Chrome/Firefox with disabled flash plugin from watir script? thread, there is also --disable-internal-flash switch, but it is also relevant to the chrome's internal flash plugin.

Browserstack's documentation suggests to follow the principle "the guillotine is the best dandruff cure" and to disable all plugins by using --disable-plugins switch:

To disable Flash in Chrome, create a chromeOptions capability, and
  pass the --disable-plugins argument to the capability.

Is there a way to disable all flash plugins without disabling all plugins in Chrome?

For instance, would be perfect to have a preference to list all of the plugins that needs to be turned off:

```<code>plugins.disabled: ['Adobe Flash Player', 'pepperflash']
</code>```

答:
chrome://plugins doesn't exist anymore in Chrome 57 and above. Method proposed by alecxe in accepted answer unfortunately doesn't work for me.

I was able to workaround this issue by turning on mobile emulation on ChromeDriver. Example code for some languages can be found here: https://sites.google.com/a/chromium.org/chromedriver/mobile-emulation

Example code for java from the above page:

Map<String, String> mobileEmulation = new HashMap<String, String>();
mobileEmulation.put("deviceName", "Google Nexus 5");

Map<String, Object> chromeOptions = new HashMap<String, Object>();
chromeOptions.put("mobileEmulation", mobileEmulation);
DesiredCapabilities capabilities = DesiredCapabilities.chrome();
capabilities.setCapability(ChromeOptions.CAPABILITY, chromeOptions);
WebDriver driver = new ChromeDriver(capabilities);
```

<p>You can also specify your own screen resolution, pixel ratio and even userAgent.</p>

<pre class="lang-java prettyprint-override"><code>Map<String, Object> deviceMetrics = new HashMap<String, Object>();
deviceMetrics.put("width", 1920);
deviceMetrics.put("height", 1080);
deviceMetrics.put("pixelRatio", 1.0);

Map<String, Object> mobileEmulation = new HashMap<String, Object>();
mobileEmulation.put("deviceMetrics", deviceMetrics);
mobileEmulation.put("userAgent", "Mozilla/5.0 (Linux; Android 4.2.1; en-us; Nexus 5 Build/JOP40D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19");

Map<String, Object> chromeOptions = new HashMap<String, Object>();
chromeOptions.put("mobileEmulation", mobileEmulation);
DesiredCapabilities capabilities = DesiredCapabilities.chrome();
capabilities.setCapability(ChromeOptions.CAPABILITY, chromeOptions);
WebDriver driver = new ChromeDriver(capabilities);
</code>```

This will work with RemoteWebDriver also.

Title: Disabling flash in Chrome

Body:
One of our internal applications has a flash object on a page. I need to test one of the corner cases when there is no flash plugin available/installed in the browser: neither the internal (pepperflash), nor the system-wide adobe flash player plugin.

According to the List of Chromium Command Line Switches documentation page, there is a relevant command-line switch:

--disable-bundled-ppapi-flash - Disables the bundled PPAPI version of Flash.

But, this would turn off only the pepperflash internal chrome plugin.

According to the How to run Chrome/Firefox with disabled flash plugin from watir script? thread, there is also --disable-internal-flash switch, but it is also relevant to the chrome's internal flash plugin.

Browserstack's documentation suggests to follow the principle "the guillotine is the best dandruff cure" and to disable all plugins by using --disable-plugins switch:

To disable Flash in Chrome, create a chromeOptions capability, and
  pass the --disable-plugins argument to the capability.

Is there a way to disable all flash plugins without disabling all plugins in Chrome?

For instance, would be perfect to have a preference to list all of the plugins that needs to be turned off:

plugins.disabled: ['Adobe Flash Player', 'pepperflash']

Body:
chrome://plugins doesn't exist anymore in Chrome 57 and above. Method proposed by alecxe in accepted answer unfortunately doesn't work for me.

I was able to workaround this issue by turning on mobile emulation on ChromeDriver. Example code for some languages can be found here: https://sites.google.com/a/chromium.org/chromedriver/mobile-emulation

Example code for java from the above page:

Map<String, String> mobileEmulation = new HashMap<String, String>();
mobileEmulation.put("deviceName", "Google Nexus 5");

Map<String, Object> chromeOptions = new HashMap<String, Object>();
chromeOptions.put("mobileEmulation", mobileEmulation);
DesiredCapabilities capabilities = DesiredCapabilities.chrome();
capabilities.setCapability(ChromeOptions.CAPABILITY, chromeOptions);
WebDriver driver = new ChromeDriver(capabilities);

You can also specify your own screen resolution, pixel ratio and even userAgent.

Map<String, Object> deviceMetrics = new HashMap<String, Object>();
deviceMetrics.put("width", 1920);
deviceMetrics.put("height", 1080);
deviceMetrics.put("pixelRatio", 1.0);

Map<String, Object> mobileEmulation = new HashMap<String, Object>();
mobileEmulation.put("deviceMetrics", deviceMetrics);
mobileEmulation.put("userAgent", "Mozilla/5.0 (Linux; Android 4.2.1; en-us; Nexus 5 Build/JOP40D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19");

Map<String, Object> chromeOptions = new HashMap<String, Object>();
chromeOptions.put("mobileEmulation", mobileEmulation);
DesiredCapabilities capabilities = DesiredCapabilities.chrome();
capabilities.setCapability(ChromeOptions.CAPABILITY, chromeOptions);
WebDriver driver = new ChromeDriver(capabilities);

This will work with RemoteWebDriver also.


问:
C# class parameter
```<code> namespace ConsoleApplication3
{
    class Program
    {
        static void Main(string[] args)
        {
            A a = new A();
            B b = new B(a);
            C c = new C(a);

            Console.WriteLine(a.intval + " " +a.strval);
            Console.ReadLine();
        }
    }

    class A
    {
        public int intval { get; set; }
        public string strval { get; set; }
    }
    class B
    {
        public A _a;
        public B(A a)
        {
            _a = a;
            _a.intval += 100;
            _a.strval += "From B;";
        }
    }
    class C
    {
        A _a;
        public C(A a)
        {
            _a = a;
            _a.intval += 1000;
            _a.strval += "From C;";
        }
    }
}
</code>```

In above code, why the instance "b" and “c” could set value to instance "a"?

In my guess, the Class B and C have their own variables "a", when we call "B b = new B(a);" or "C c = new C(a);", the value should be changed on their own fields and the variable "a" in Main would be impacted?

But, i'm wrong. Could you please help me understand the result? Thank you very much.

答:
It all makes sense when you understand what a variable is. A variable is a placeholder for a value, and what is this value?

If the variable type is a reference type, then the value stored
inside the variable is simply the address in memory of where the
instance it is currently pointing to resides.

If the variable type is a value type then the value stored inside the variable is the instance itself.

In your case, a's type is a reference type (class), so this means that the value stored in a is just the address where new A() lives.

Because arguments, by default, are passed by value in C#, when you do new B(a) or new C(a), a copy of the value in a is made, that is, a copy of the address. But all addresses, original or copied, point to the same object and that is why you are seeing the behavior you are seeing.

Title: C# class parameter

Body:
 namespace ConsoleApplication3
{
    class Program
    {
        static void Main(string[] args)
        {
            A a = new A();
            B b = new B(a);
            C c = new C(a);

            Console.WriteLine(a.intval + " " +a.strval);
            Console.ReadLine();
        }
    }

    class A
    {
        public int intval { get; set; }
        public string strval { get; set; }
    }
    class B
    {
        public A _a;
        public B(A a)
        {
            _a = a;
            _a.intval += 100;
            _a.strval += "From B;";
        }
    }
    class C
    {
        A _a;
        public C(A a)
        {
            _a = a;
            _a.intval += 1000;
            _a.strval += "From C;";
        }
    }
}

In above code, why the instance "b" and “c” could set value to instance "a"?

In my guess, the Class B and C have their own variables "a", when we call "B b = new B(a);" or "C c = new C(a);", the value should be changed on their own fields and the variable "a" in Main would be impacted?

But, i'm wrong. Could you please help me understand the result? Thank you very much.


问:
How to change the header color of csv in java using ICsvBeanWriter
I am using ICsvBeanWriter to generate the CSV file over the REST API, my code looks like

```<code>// uses the Super CSV API to generate CSV data from the model data
    ICsvBeanWriter csvWriter = new CsvBeanWriter(response.getWriter(),
    CsvPreference.STANDARD_PREFERENCE);

    String[] header = { "Title", "Description", "Author", "Publisher",
                    "isbn", "PublishedDate", "Price" };

    csvWriter.writeHeader(header);
</code>```

I want to set the header color to some different color rather than the default one. Please tell me how i can do this?

答:
There are no colors in CSV.

The CSV is a textual, data-only format that does not allow any styling information.

Body:
I am using ICsvBeanWriter to generate the CSV file over the REST API, my code looks like

// uses the Super CSV API to generate CSV data from the model data
    ICsvBeanWriter csvWriter = new CsvBeanWriter(response.getWriter(),
    CsvPreference.STANDARD_PREFERENCE);

    String[] header = { "Title", "Description", "Author", "Publisher",
                    "isbn", "PublishedDate", "Price" };

    csvWriter.writeHeader(header);

I want to set the header color to some different color rather than the default one. Please tell me how i can do this?


问:
E/art﹕ Failed sending reply to debugger: Broken pipe, but application still runs
When I run my application many lines appear in the logcat but only one error:

E/art﹕ Failed sending reply to debugger: Broken pipe.

What does it mean? And how can I fix it?

答: I had a breakpoint in a return statement, when I removed it everything ran as it should. So give that a try too (removing all breakpoints).</p>


问:
How to include a .lib file dynamically?
I've got a problem with my project. I am developing it on Qt Creator, and I need to add a .lib file to my project. So, I wrote this line in my .pro :

```<code>LIBS += "C:\My_Path\My_Project\lib\file.lib"
</code>```

This is working fine. My only issue is that I need to write the entire path to the .lib file. Since it's a group project, it needs to be compilable on other computers without changing the path to this file every times.

I tried many syntaxes, like :

```<code>LIBS += -L"lib/" -l"file.lib"
</code>```

or

```<code>LIBS += "lib\file.lib"
</code>```

or

```<code>LIBS += "file.lib"
</code>```

(putting the .lib file at the root and adding it to the project in Qt Creator)

None of them works :/

I also tried to add the .lib file in a QResource file but a syntax like this one :

```<code>LIBS += ":/lib/file.lib"
</code>```

in a .pro file doesn't seem to work...

I am now running out of ideas :(

Help please :)

答:
Did you try

LIBS += -Llib -lfile

or

LIBS += -L./lib -lfile?

Remember if you aren't using the full path, you don't add .lib to the library name and you don't use quotes.  If the path has spaces (or you just want to be safe), use $$quote(-L<path name>)

As stated here the Unix style paths work on Windows as well where you normally need to provide the full path.  qmake will fill it in for you.

I converted

LIBS += ../../lib/phraseBox.lib

to

LIBS += $$quote(-L../../lib) -lphraseBox

and

LIBS += $$quote(-L../../lib) phraseBox.lib

In one of my project with no problem on Windows.  You might want to post your project files somewhere, or post the actual error messages to narrow this down.

Title: How to include a .lib file dynamically?

Body:
I've got a problem with my project. I am developing it on Qt Creator, and I need to add a .lib file to my project. So, I wrote this line in my .pro :

LIBS += "C:\My_Path\My_Project\lib\file.lib"

This is working fine. My only issue is that I need to write the entire path to the .lib file. Since it's a group project, it needs to be compilable on other computers without changing the path to this file every times.

I tried many syntaxes, like :

LIBS += -L"lib/" -l"file.lib"

or

LIBS += "lib\file.lib"

or

LIBS += "file.lib"

(putting the .lib file at the root and adding it to the project in Qt Creator)

None of them works :/

I also tried to add the .lib file in a QResource file but a syntax like this one :

LIBS += ":/lib/file.lib"

in a .pro file doesn't seem to work...

I am now running out of ideas :(

Help please :)


问:
Angular2 click event not working
I'm facing an issue with an angular2 click event, it's not launching a simple console.log or an alert.

Here I post my component template:

```<code><div class="col-md-4">
<div *ngFor="let phone of phones">
{{phone.text}}
</div>
<input class="form-control" type="text" [(ngModel)]="phone"/>
<button class="btn btn-primary" (click)="console.log('clicked');" type="button">Call</button>
</div>
</code>```

When I click the button, there is nothing in the console.

I tried to execute a component function, with no luck as well.

I'm doing it the same way than here:
http://learnangular2.com/events/

Do you guys need more files? I just don't understand why this is not working

Thank you so much,
Daniel

Edit:

Ok so now I'm doing it like this:

Template:

```<code><div class="col-md-4">
<div *ngFor="let phone of phones">
    {{phone.text}}
</div>
<input class="form-control" type="text" [(ngModel)]="phone"/>
<button class="btn btn-primary" (click)="callPhone();" type="button">Call</button>
</div>
</code>```

And my ts file component:

```<code>import {Component, OnInit, OnDestroy} from '@angular/core';
import {FormControl} from '@angular/forms';
import {CallService} from '../call.service';

@Component({
moduleId: module.id,
selector: 'app-call-formular',
templateUrl: './call-formular.component.html',
styleUrls: ['./call-formular.component.css'],
providers: [CallService]
})
export class CallFormularComponent implements OnInit, OnDestroy {

phones = [];
connection;
phone;

constructor(private callService: CallService) {
}

callPhone(): any {
    console.log('callPhone executed.');
}

ngOnInit() {
    this.connection = this.callService.getPhones().subscribe(phone =>
{
        this.phones.push(phone);
    });
}

ngOnDestroy() {
    this.connection.unsubscribe();
}

}
</code>```

And still not launching my click event

答:
Add your logic in backend/typescript:

```<code> CallClick(): any {
    console.log('clicked');
}
</code>```

And at html side:

```<code><button class="btn btn-primary" (click)="CallClick()" type="button">Call</button>
</code>```

Title: Angular2 click event not working

Body:
I'm facing an issue with an angular2 click event, it's not launching a simple console.log or an alert.

Here I post my component template:

{{phone.text}}

<input class="form-control" type="text" [(ngModel)]="phone"/>
<button class="btn btn-primary" (click)="console.log('clicked');" type="button">Call</button>

When I click the button, there is nothing in the console.

I tried to execute a component function, with no luck as well.

I'm doing it the same way than here:
http://learnangular2.com/events/

Do you guys need more files? I just don't understand why this is not working

Thank you so much,
Daniel

Edit:

Ok so now I'm doing it like this:

Template:

    {{phone.text}}

<input class="form-control" type="text" [(ngModel)]="phone"/>
<button class="btn btn-primary" (click)="callPhone();" type="button">Call</button>

And my ts file component:

import {Component, OnInit, OnDestroy} from '@angular/core';
import {FormControl} from '@angular/forms';
import {CallService} from '../call.service';

@Component({
moduleId: module.id,
selector: 'app-call-formular',
templateUrl: './call-formular.component.html',
styleUrls: ['./call-formular.component.css'],
providers: [CallService]
})
export class CallFormularComponent implements OnInit, OnDestroy {

phones = [];
connection;
phone;

constructor(private callService: CallService) {
}

callPhone(): any {
    console.log('callPhone executed.');
}

ngOnInit() {
    this.connection = this.callService.getPhones().subscribe(phone =>
{
        this.phones.push(phone);
    });
}

ngOnDestroy() {
    this.connection.unsubscribe();
}

}

And still not launching my click event

Body:
Add your logic in backend/typescript:

 CallClick(): any {
    console.log('clicked');
}

And at html side:

<button class="btn btn-primary" (click)="CallClick()" type="button">Call</button>


问:
C/C++ Search for a folder from a root location and return absolute path
I'm trying to make a program which copies a folder from one location to another, but without knowing the exact path of source folder, only a root location.

I've managed to find a cmd command (xcopy 'sourcePath' E:\Destination\Target /E /I /H) but the problem is that sourcePath is not always the same

e.g.

Root location: D:\Root

Destination location: E:\Destination

In root location I want to search for a folder named Target which can be anywhere in a subdirectory (e.g. D:\Root\Dir1\Subdir1\Target or D:\Root\Dir2\Subdir2\SSubdir2\Target or ...)

So I don't know the exact number of subdirectories in root location and I'm wondering if there is a method which can search for that specific folder starting from root location and if it finds it, to return the absolute path of it.

答:
As far as I understand your question, you need to find a directory called "Target", and then copy it.

In order to implement these 2 steps, I invite you to check those 2 stackoverflow questions, which in my opinion contain the information you need :

recursive file search

how to copy folder from one path to another in c++
Best regards


问:
Active Users SQL query
I'm trying to graph active users in a webapp. My database consists of two main tables, user and task. task has a user_id.

My definition of active users: is a user who has created more than 2 tasks within two weeks of a given end date.

So, I need an SQL query that gives me the number of active users between a given start and end date. I was able to do this by putting the query inside a loop, pulling the results each time, but I'd love to be able to do it in a single query.

The returned data should be something like:

```<code>Date         Count
2010-01-01   4
2010-01-02   3
2010-01-03   5
</code>```

Edit to clarify desired dataset.

答:
```<code>SELECT t.taskdate, COUNT(DISTINCT u.user_id)
    FROM user u
        INNER JOIN task t
            ON u.user_id = t.user_id
                AND t.taskdate BETWEEN DATE_ADD(@EndDate, INTERVAL -2 WEEK) AND @EndDate
    GROUP BY t.taskdate
    ORDER BY t.taskdate
</code>```

Title: Active Users SQL query

Body:
I'm trying to graph active users in a webapp. My database consists of two main tables, user and task. task has a user_id.

My definition of active users: is a user who has created more than 2 tasks within two weeks of a given end date.

So, I need an SQL query that gives me the number of active users between a given start and end date. I was able to do this by putting the query inside a loop, pulling the results each time, but I'd love to be able to do it in a single query.

The returned data should be something like:

Date         Count
2010-01-01   4
2010-01-02   3
2010-01-03   5

Edit to clarify desired dataset.


问:
How to generalize this C# code?
I have this code which initializes winforms textboxes.

```<code>txt0.Text = steps[0];
txt1.Text = steps[1];
txt2.Text = steps[2];
txt3.Text = steps[3];
</code>```

I'd like to generalize it like this:

```<code>for (int i = 0; i < steps.Length; i++)
{
    txti.Text = steps[i];
}
</code>```

Obviously this doesn't work because the name txti does not exist in current context.
How to make it work?

EDIT:
I want to avoid creating all the textboxes and picture boxes in code and adding them to tablelayoutpanel in code.

答:
You can do it with reflection, but i wouldn't recommend it to solve this task.

Instead have a List and loop through it.

```<code>List<TextBox> textBoxes = new List<TextBox> {txt0,txt1,txt2,txt3};
for (int i = 0; i < textBoxes.Length; i++)
{
    textBoxes[i].Text = steps[i];
}
</code>```

Title: How to generalize this C# code?

Body:
I have this code which initializes winforms textboxes.

txt0.Text = steps[0];
txt1.Text = steps[1];
txt2.Text = steps[2];
txt3.Text = steps[3];

I'd like to generalize it like this:

for (int i = 0; i < steps.Length; i++)
{
    txti.Text = steps[i];
}

Obviously this doesn't work because the name txti does not exist in current context.
How to make it work?

EDIT:
I want to avoid creating all the textboxes and picture boxes in code and adding them to tablelayoutpanel in code.

Body:
You can do it with reflection, but i wouldn't recommend it to solve this task.

Instead have a List and loop through it.

List<TextBox> textBoxes = new List<TextBox> {txt0,txt1,txt2,txt3};
for (int i = 0; i < textBoxes.Length; i++)
{
    textBoxes[i].Text = steps[i];
}


答:
The code in the original question could be generalized as follows.</p>

```<code>var TextBoxes = new TextBox[]{ txt0, txt1, txt2, txt3 };
for (int i = 0; i < TextBoxes.Length; i++)
{
    TextBoxes[i].Text = steps[i];
}
</code>```

Title: How to generalize this C# code?

Body:
The code in the original question could be generalized as follows.

var TextBoxes = new TextBox[]{ txt0, txt1, txt2, txt3 };
for (int i = 0; i < TextBoxes.Length; i++)
{
    TextBoxes[i].Text = steps[i];
}


问:
Pandas: how to operate with each pivottable value?
This is the continuation of this. Let's say I have code that does this table I want

```<code>df.groupby('A')['B'].value_counts().unstack().stack(dropna=False
                ).reset_index(name="Count").set_index(['A', 'B'])

|----|----|-------|
| A  | B  | Count |
| a1 | b1 |  1    |
|    | b2 |  1    |
|    | b3 |  NaN  |
| a2 | b1 |  1    |
|    | b2 |  NaN  |
|    | b3 |  1    |
</code>```

The problem is that there is the case where B column might have multivariate values, e.g. many unique values. So the groupping A column values are a bit far away :) Eventually, this all should be stored in some Excel format file df.to_excel(). The solution was proposed to generate such as Excel files per A values. E.g. instead of groupped.xlsx  where you have all this pivot table in once, to have A_a1.xlsx, A_a2.xlsx files.

Question: how do you do it?

I have some options in mind like to get the list of unique A values and just do something like df_loc = df.loc[df['A'] == 'a1'], but maybe there is more cool way?

答:
If I understand correctly you're looking for an individual excel file for each A value? If so, the following should work:

for i in df.a.unique():
  df[df['a'] == i].to_excel(path+_i)

You can tweak the path for your needs but this is a pretty easy way to do what you're looking for.

Body:
This is the continuation of this. Let's say I have code that does this table I want

df.groupby('A')['B'].value_counts().unstack().stack(dropna=False
                ).reset_index(name="Count").set_index(['A', 'B'])

|----|----|-------|
| A  | B  | Count |
| a1 | b1 |  1    |
|    | b2 |  1    |
|    | b3 |  NaN  |
| a2 | b1 |  1    |
|    | b2 |  NaN  |
|    | b3 |  1    |

The problem is that there is the case where B column might have multivariate values, e.g. many unique values. So the groupping A column values are a bit far away :) Eventually, this all should be stored in some Excel format file df.to_excel(). The solution was proposed to generate such as Excel files per A values. E.g. instead of groupped.xlsx  where you have all this pivot table in once, to have A_a1.xlsx, A_a2.xlsx files.

Question: how do you do it?

I have some options in mind like to get the list of unique A values and just do something like df_loc = df.loc[df['A'] == 'a1'], but maybe there is more cool way?


问:
Imagemap; show text when hovering over certain area
logocopy3
Im having issues linking a specific part of an image (area map) with the hover effect. Currently I have the ability to click each section of the imagemap and it directs me to the required page, however I would like the hover effect to be displayed before the user clicks so they know which page they are navigating to.
Basically Im trying to display a text which stays in the same position sitting  above the image map each time the user hovers over a specific area. </p>

<p>My code is as follows: </p>

```<code> <div>
<img src="logocopy3.png" id="logo" style="width: 260px; max-width: 100%;
height: auto;" alt="" usemap="#map" />

<map name="map">
    <area shape="circle" coords="243,132,41" href="Ktrack.html" alt=''/>
    <area shape="circle" coords="189,223,41" alt='' href="Kinsurance.html" />
    <area shape="circle" coords="69,205,29" alt='' href='Khealth.html'/>
    <area shape="circle" coords="9,131,42" alt='' href='Klocklock.html' />
    <area shape="circle" coords="128,49,81" alt='' href='index.html'/>
</map>

</div>
</code>```

答:
I have created a demo using tooltipster jquery plugin and this is the best way I have found to do so ;)

$(document).ready(function() {
  $('.tooltip').tooltipster({

  });
});```
<pre class="snippet-code-html lang-html prettyprint-override"><code><script src="http://code.jquery.com/jquery-1.10.0.min.js"></script>
<script src="http://iamceege.github.io/tooltipster/dist/js/tooltipster.bundle.js"></script>
<link href="http://iamceege.github.io/tooltipster/dist/css/tooltipster.bundle.min.css" rel="stylesheet" />

<div>
  <img src="https://i.stack.imgur.com/JRo8A.png" id="logo" style="width: 260px; max-width: 100%;
height: auto;" alt="" usemap="#map" />

  <map name="map">
    <area shape="circle" coords="243,132,41" href="Ktrack.html" class="tooltip" title="This is my image's tooltip message for area 1!" />
    <area shape="circle" coords="189,223,41" alt='' href="Kinsurance.html"  class="tooltip" title="This is my image's tooltip message for area 2!"/>
    <area shape="circle" coords="69,205,29" alt='' href='Khealth.html' class="tooltip" title="This is my image's tooltip message for area 3!"/>
    <area shape="circle" coords="9,131,42" alt='' href='Klocklock.html'  class="tooltip" title="This is my image's tooltip message for area 5!" />
    <area shape="circle" coords="128,49,81" alt='' href='index.html' class="tooltip" title="This is my image's tooltip message for area 6!" />
</map>

</div></code>```

Body:
logocopy3
Im having issues linking a specific part of an image (area map) with the hover effect. Currently I have the ability to click each section of the imagemap and it directs me to the required page, however I would like the hover effect to be displayed before the user clicks so they know which page they are navigating to.
Basically Im trying to display a text which stays in the same position sitting  above the image map each time the user hovers over a specific area.

My code is as follows:

<map name="map">
    <area shape="circle" coords="243,132,41" href="Ktrack.html" alt=''/>
    <area shape="circle" coords="189,223,41" alt='' href="Kinsurance.html" />
    <area shape="circle" coords="69,205,29" alt='' href='Khealth.html'/>
    <area shape="circle" coords="9,131,42" alt='' href='Klocklock.html' />
    <area shape="circle" coords="128,49,81" alt='' href='index.html'/>
</map>

Body:
I have created a demo using tooltipster jquery plugin and this is the best way I have found to do so ;)

$(document).ready(function() {
  $('.tooltip').tooltipster({

  });
});

<script src="http://code.jquery.com/jquery-1.10.0.min.js"></script>
<script src="http://iamceege.github.io/tooltipster/dist/js/tooltipster.bundle.js"></script>
<link href="http://iamceege.github.io/tooltipster/dist/css/tooltipster.bundle.min.css" rel="stylesheet" />

<div>
  <img src="https://i.stack.imgur.com/JRo8A.png" id="logo" style="width: 260px; max-width: 100%;
height: auto;" alt="" usemap="#map" />

  <map name="map">
    <area shape="circle" coords="243,132,41" href="Ktrack.html" class="tooltip" title="This is my image's tooltip message for area 1!" />
    <area shape="circle" coords="189,223,41" alt='' href="Kinsurance.html"  class="tooltip" title="This is my image's tooltip message for area 2!"/>
    <area shape="circle" coords="69,205,29" alt='' href='Khealth.html' class="tooltip" title="This is my image's tooltip message for area 3!"/>
    <area shape="circle" coords="9,131,42" alt='' href='Klocklock.html'  class="tooltip" title="This is my image's tooltip message for area 5!" />
    <area shape="circle" coords="128,49,81" alt='' href='index.html' class="tooltip" title="This is my image's tooltip message for area 6!" />
</map>

</div>


问:
How to split these strings into an array
I'm looking for a method to split the following line of text into an array.

Here is some text\r\n"here is another line"\r\nAnd another line

Such that the resultant array is:

Here is some text

\r\n

"

here is another line

"

\r\n

And another line

Note there are essentially two delimeters here, " and \r\n.

I need to do this in C++ and there could be additional delimeters in the future.

Any ideas?

Thanks in advance.

Edit: No, this is not homework.

Here's what I have so far:

```<code>const RWCString crLF = "\r\n";
const RWCString doubleQuote = "\"";

    RWTValOrderedVector<RWCString> Split(const RWCString &value, const RWCString &specialContent)
    {
        RWTValOrderedVector<RWCString> result;

        unsigned index = 0;

        RWCString str = value;

        while ( ( index = str.index( specialContent, 0, RWCString::ignoreCase ) ) != RW_NPOS )
        {
            RWCString line = str(0, index);

            result.append(line);
            result.append(specialContent);

            str = str(index, str.length() - index);
            str = str(specialContent.length(), str.length() - specialContent.length());
        }

        if (str.length() > 0)
        {
            result.append(str);
        }

        return result;
    }

        void replaceSpecialContents(const RWCString &value)
        {

            RWTValOrderedVector<RWCString> allStrings;

            RWTValOrderedVector<RWCString> crLFStrings = Split(value, crLF);

            for (unsigned i=0; i<crLFStrings.entries(); i++)
            {
            RWTValOrderedVector<RWCString> dqStrings = Split(crLFStrings[i], doubleQuote);

                if (dqStrings.entries() == 1)
                {
                    allStrings.append(crLFStrings[i]);
                }
                else
                {
                    for (unsigned j=0; j<dqStrings.entries(); j++)
                    {
                        allStrings.append(dqStrings[j]);
                    }
                }
            }

    }
</code>```

答: getline has an optional delimiter, so you can use stringstream to do it with very little effort on your part.  The downside is that (I believe) it only works with one delimiter at a time.

Body:
I'm looking for a method to split the following line of text into an array.

Here is some text\r\n"here is another line"\r\nAnd another line

Such that the resultant array is:

Here is some text

\r\n

"

here is another line

"

\r\n

And another line

Note there are essentially two delimeters here, " and \r\n.

I need to do this in C++ and there could be additional delimeters in the future.

Any ideas?

Thanks in advance.

Edit: No, this is not homework.

Here's what I have so far:

const RWCString crLF = "\r\n";
const RWCString doubleQuote = "\"";

    RWTValOrderedVector<RWCString> Split(const RWCString &value, const RWCString &specialContent)
    {
        RWTValOrderedVector<RWCString> result;

        unsigned index = 0;

        RWCString str = value;

        while ( ( index = str.index( specialContent, 0, RWCString::ignoreCase ) ) != RW_NPOS )
        {
            RWCString line = str(0, index);

            result.append(line);
            result.append(specialContent);

            str = str(index, str.length() - index);
            str = str(specialContent.length(), str.length() - specialContent.length());
        }

        if (str.length() > 0)
        {
            result.append(str);
        }

        return result;
    }

        void replaceSpecialContents(const RWCString &value)
        {

            RWTValOrderedVector<RWCString> allStrings;

            RWTValOrderedVector<RWCString> crLFStrings = Split(value, crLF);

            for (unsigned i=0; i<crLFStrings.entries(); i++)
            {
            RWTValOrderedVector<RWCString> dqStrings = Split(crLFStrings[i], doubleQuote);

                if (dqStrings.entries() == 1)
                {
                    allStrings.append(crLFStrings[i]);
                }
                else
                {
                    for (unsigned j=0; j<dqStrings.entries(); j++)
                    {
                        allStrings.append(dqStrings[j]);
                    }
                }
            }

    }


问:
Computing a ranking with Java 8 Stream API
A common problem when processing data is to build a ranking of items
based on some property.

The ranking operation consists
in mapping the items to a set of ordinal numbers (called ranking).
In presence of ties (i.e. two items having the same ranking) several
strategies can be used, in this context we will assume the standard competition ranking (a.k.a. "1224" ranking) is used.

The question I'd like to investigate here is what is the "best" way
of doing this using the streaming API. Where best may mean, most elengant,
most efficient, simplest, etc.

Case study

Let's start with a very simple example: a stream of words (i.e. Strings)
out of which a ranking by decreasing lengths should be created.
If we take the first paragraph of this document, i.e.

```<code>A common problem when processing data is to build
a ranking of itemsbased on some property
</code>```

we would get the following ranking (by inverse lengths)
should be obtained:

```<code>1 - processing (10)
2 - property (8)
3 - problem (7)
3 - ranking (7)
5 - common (6)
6 - build (5)
6 - items (5)
6 - based (5)
9 - when (4)
9 - data (4)
9 - some (4)
12 - is (2)
12 - to (2)
12 - of (2)
12 - on (2)
16 - A (1)
16 - a (1)
</code>```

When two items share the same ranking property value, they are assigned the same ranking.

Questions

The main question here is:

what stream API construct do you used to compute the ranking and how
  you organize your code?

A second related question is

how you represent the result of the ranking computation?

答:
The two questions are addressed one after the other

ranking representation

ranking procedure

Ranking representation

The typical ranking, as shown above, is a list of items preceded by their relative ranking value.

There are, at least, two possible implementations for the return value
of a ranking.

Option 1: List<Rank>

A possible internal representation of the ranking could be a list of
elements containing both the ranking value and the item. For instance
we could define a class:

```<code>public class Rank<T> {
  protected int ranking;
  protected T item;
  protected Rank(int r, T i) { ranking=t; item=i; }
  public int getRanking() { return ranking; }
  public T getItem() { return item; }
  static <T> Rank<T> factory(int ranking, T item) {
      return new Rank<T>(ranking,item);
  }
}
</code>```

Or, with a somewhat more esotheric code:

```<code>public interface Rank<T> {
      int getRanking();
      T getItem();
      static <T> Rank<T> factory(int ranking, T item) {
          return new Rank<T>(){
               public int getRanking() { return ranking; }
               public T getItem() { return item; }
          };}
}
</code>```

The resulting ranking will be returned as a List<Rank>.
The list must be returned sorted by descending ranking and processed in that order.

A potential disadvantage of such solution is the need for a new ad-hoc class or interface (i.e. Rank).

Option 2: SortedMap<Integer,List<T>>

An alternative solution that uses only predefined standard classes and intefaces is based on a map.

The keys of the map correspond to the ranking values, while the values of the map consist in lists that contain the items sharing that ranking.

The return type of the ranking would be a SortedMap<T,List<T>>.
The sorted map will be implicitly sorted and can be traversed according to the natural order of the key.

This latter solution seems preferable because it does not require any new class and can be better understood.

Ranking Procedure

The ranking computation procedure can be implemented in different ways.
Here two approaches are examined.

In all cases we need to have a function that serves the purpose
of extracting the ranking property:

```<code>Function<String,Integer> propertyExtractor = String::length;
</code>```

Typically, the property type should be comparable, though to be more general (e.g. to sort strings in decreasing order) the property comparator can be defined:

```<code>Comparator<Integer> propertyComparator = reverseOrder();
</code>```

The two approaches are illustrated, referring to the case study described above, using a words stream as a starting point:

```<code>String paragraph = "A common problem when processing data is to build  a ranking of items based on some property";
Stream<String> words = Stream.of(paragraph.split(" "));
</code>```

Sorting by ranking property

Basic procedure

An initial naive version of the procedure can be defined using a supporting map data structure upon which the stream operations work by means of side effects:

```<code>SortedMap<Integer,List<String>> ranking = new TreeMap<>();
</code>```

The procedure is as follows:

Sort the elements of the stream

```<code>words.sorted(comparing(propetyExtractor,propertyComparator))
</code>```

Assign the ranking, starting with 1 and incrementing it
any time the property changes. The ranking has to be incremented
by the number of items that shared the current ranking.

```<code>.forEach( item -> {
    Integer property = propertyExtractor.apply(item);
    if(ranking.isEmpty()){
        ranking.put(1,new LinkedList<String>());
    }else{
        Integer rank = ranking.lastKey();
        List<String> items = ranking.get(rank);
        if(! property.equals(propertyExtractor.apply(items.get(0)))) {
            ranking.put(rank+items.size(), new LinkedList<String>());
        }
    }
    ranking.get(ranking.lastKey()).add(item);
});
</code>```

The above code works as follows:

The initial sequence of items is unsorted:

{"DD","BBB","F","CCC","AAAA","EE"}

Step 1 sorts the item using the propertyExtractor and the relative propertyComparator, i.e. by string length:

{"AAAA","BBB","CCC","DD","EE","F"}

then for each element (in order) a new entry in the map is added
any time the lenght of the new element differs from the previous
element lenght

When "AAAA" is processed (first item) a new entry is added to
the map with key (i.e. ranking) = 1:

ranking : {1=["AAAA"]}

As the second item "BBB" is processed, since its lenght (3)
is different from the last element length (4, the lenght of "AAAA")
a new entry is added with un updated ranking value:

ranking : {1=["AAAA"],2=["BBB"]}

As the third item "CCC" is processed, since its lenght (3)
is equal to the last element length, the item is added
to the entry list

ranking : {1=["AAAA"],2=["BBB","CCC"]}

etc.

Usage of collector

A more functional-style version can be defined by using a collector that encapsulates the data structure where the results are accumulated.
In practice we can write a single stream expression that returns the ranking map:

```<code>SortedMap<Integer,List<String>> ranking =
words.sorted(comparing(propertyExtractor,propertyComparator))
     .collect(TreeMap::new, // supplier

             (rank, item) -> {  // accumulator
                 Integer property = propertyExtractor.apply(item);
                 if(rank.isEmpty()){
                     rank.put(1,new LinkedList<String>());
                 }else{
                     Integer r = rank.lastKey();
                     List<String> items = rank.get(r);
                     Integer prevProp = propertyExtractor.apply(items.get(0))
                     if(! property.equals(prevProp)) {
                         rank.put(r+items.size(), new LinkedList<String>());
                     }
                 }
                 rank.get(rank.lastKey()).add(item);
             },

             (rank1,rank2) -> { // combiner
                 \\...
             }
     );
</code>```

Combining results

The combiner method that is left undefiened in the above code deserves some additional reflections.

The functional interface is involved when the collection is performed in parallel; it is used to combine two partial results of the accumulation into a single one. In this case, it has to implement the interface BiConsumer<R,R> and it is supposed to combine the two accumulated rankings - rank1 and rank2 - into the first one.

A possible implementation of the supplier is:

```<code>BiConsumer<SortedMap<Integer,List<String>>,
             SortedMap<Integer,List<String>>> combiner =
(rank1,rank2) -> {
        int lastRanking = rank1.lastKey();
        int offset = lastRanking + rank1.get(lastRanking).size()-1;
        if( propertyExtractor.apply(rank1.get(lastRanking).get(0))
            == propertyExtractor.apply(rank2.get(rank2.firstKey()).get(0)) ){
            rank1.get(lastRanking).addAll(rank2.get(rank2.firstKey()));
            rank2.remove(rank2.firstKey());
        }
        rank2.forEach((r,items) -> {rank1.put(offset+r, items);} );
}
</code>```

The collector has no declared properties, so the elements will be processed in order and then composed in order. E.g. the sorted list of items is divided into two parts, then the first part is processed through with one copy of the collector producing as result the map rank1; in parallel, the second part is processed giving as result rank2.

Let us suppose the streams are processed in parallel, in two concurent
execution of the collect operations:

the initial sorted stream (result of the sorted() operation is
divided into two stream, maintaining the orded

sub-stream 1: {"AAAA","BBB","CCC"}

sub-stream 2: {"DD","EE","F"}

two distinct collectors operate in parallel, on each sub-stream
the result are two maps contain the partial ranking of each sub-stream:

rank1 = {1=["AAAA"],2=["BBB","CCC"]}

rank2 = {1=["DD","EE"],3=["F"]}

The combiner operation should merge rank2 into rank1, in practice
each entry of the rank2 operation should be added to rank1 with its
key updated. They keys are updated by adding an offset that is equal to
the key of the last entry plus the lenght of the last entry value list
minus one:

```<code>public interface Rank<T> {
      int getRanking();
      T getItem();
      static <T> Rank<T> factory(int ranking, T item) {
          return new Rank<T>(){
               public int getRanking() { return ranking; }
               public T getItem() { return item; }
          };}
}
</code>```0

In practice the entry 1=["DD","EE"] of rank2 should be turned into
4=["DD","EE"] and added to rank1.

In addition, a special case should be considered, i.e. when the items
in the last entry of rank1 and those in the first entry of rank2
share the same ranking property value. E.g. for string length:

rank1 = {1=["AAAA"],2=["BBB","CCC"]}

rank2 = {1=["DDD"],2=["EE"],3=["F"]}

When this case occurs, the items in the rank2 first entry list
must be added to this in the last rank1 entry list, and then the
first entry removed.
That is the above maps should be transformed into:

rank1 = {1=["AAAA"],2=["BBB","CCC","DDD"]}

rank2 = {~~1=["DDD"],~~2=["EE"],3=["F"]}

Then the entries of rank2 can be updated and added to rank1 as
described above.

Grouping by ranking property

Basic procedure

As for the sorted list version, an initial naive version of the procedure can be defined using a supporting map data structure upon which the stream operations work by means of side effects:

```<code>public interface Rank<T> {
      int getRanking();
      T getItem();
      static <T> Rank<T> factory(int ranking, T item) {
          return new Rank<T>(){
               public int getRanking() { return ranking; }
               public T getItem() { return item; }
          };}
}
</code>```1

The naive procedure is as follows:

group the items by their property in a sorted map

```<code>public interface Rank<T> {
      int getRanking();
      T getItem();
      static <T> Rank<T> factory(int ranking, T item) {
          return new Rank<T>(){
               public int getRanking() { return ranking; }
               public T getItem() { return item; }
          };}
}
</code>```2

for each entry in the above map compute the ranking

```<code>     .forEach(
        (property,items) ->
            ranking.put(ranking.isEmpty()?1:ranking.lastKey()+
                                ranking.get(ranking.lastKey()).size(),
                        items )
             );
</code>```

The above code works as follows:

The initial sequence of items is unsorted:

{"DD","BBB","F","CCC","AAAA","EE"}

Step 1 groups the item by their propertyExtractor and store them into
a sorted set whose keys are sorted through the propertyComparator, i.e.
by string length:

{4=["AAAA"],3=["BBB","CCC"],2=["DD","EE"],1=["F"]}

Step 2, creates for each entry in the intermediate map a new entry in
the result map have the ranking value as key and the same value (i.e.
the list of items) as the intermediate entry.

The ranking is computed as follows:

1 for the first entry (i.e. when the result map is still empty), or

previous ranking (ranking.lastKey()) plus number of elements
sharing the previous ranking (ranking.get(ranking.lastKey()).size()).

The result is the final ranking map:

{1=["AAAA"],2=["BBB","CCC"],4=["DD","EE"],6=["F"]}

Using a collector

The above procedure can be rewritten using a collector to avoid side effects of the operations.

Since the first step consists in a collection, we can use the predefined collector factory methdo collectingAndThen to concatenate the first collector with a function that is applied to the collector result;
such a function will perform the step 2 described above.

```<code>SortedMap<Integer,List<String>> ranking =
words.collect(
       collectingAndThen(
            groupingBy(propertyExtractor,
                         ()->new TreeMap<>(propertyComparator),
                         toList()),
            map -> map.entrySet().stream().collect(
                      TreeMap::new,
                      (rank,entry) ->
                          rank.put(rank.isEmpty()?1:rank.lastKey()+
                                        rank.get(rank.lastKey()).size(),
                                 entry.getValue() ),
                      combiner
                    )
        )
);
</code>```

Since the structure of the result, i.e. the accumulator object, is the
same as the sorted stream solution, here the same combiner can be used.

Generic solutions

The above discussion and solution applied to the special case of
a stream of Strings. But the approach can be generalized using generics.

Ranking sorting function

The solution based on the sorted stream can be enclosed in a function:

```<code>static <T,V> SortedMap<Integer,List<T>>
rank(Stream<T> stream,
     Function<T,V> propertyExtractor,
     Comparator<V> propertyComparator){
  return
  stream.sorted(comparing(propertyExtractor,propertyComparator))
        .collect(TreeMap::new,
                 (rank, item) -> {
                    V property = propertyExtractor.apply(item);
                    if(rank.isEmpty()){
                      rank.put(new Integer(1),new LinkedList<T>());
                    }else{
                      Integer r = rank.lastKey();
                      List<T> items = rank.get(r);
                      if(! property.equals(propertyExtractor.apply(items.get(0)))) {
                        rank.put(r+items.size(), new LinkedList<T>());
                      }
                    }
                    rank.get(rank.lastKey()).add(item);
                },
            (rank1,rank2) -> {
                   int lastRanking = rank1.lastKey();
                   int offset = lastRanking + rank1.get(lastRanking).size()-1;
                   if( propertyExtractor.apply(rank1.get(lastRanking).get(0))
                       == propertyExtractor.apply(rank2.get(rank2.firstKey()).get(0))){
                     rank1.get(lastRanking).addAll(rank2.get(rank2.firstKey()));
                     rank2.remove(rank2.firstKey());
                   }
                   rank2.forEach((r,items) -> {rank1.put(offset+r, items);} );
            }
    );
}
</code>```

The above method can be applied as:

```<code>SortedMap<Integer,List<String>> ranking =
            rank(words,String::length,reverseOrder());
</code>```

Ranking grouping collector

The approach based on the grouping by property value can be
encapsulated in a collector:

```<code>static <T,V> Collector<T,?,SortedMap<Integer,List<T>>>
rankingCollector(Function<T,V> propertyExtractor,
                 Comparator<V> propertyComparator){
  return
  collectingAndThen(
    groupingBy(propertyExtractor,
               ()->new TreeMap<>(propertyComparator),
               toList()),
    map -> map.entrySet().stream().collect(
            TreeMap::new,
            (rank,entry) ->
                  rank.put(rank.isEmpty()?1:rank.lastKey()+
                             rank.get(rank.lastKey()).size(),
                           entry.getValue() ),
            (rank1,rank2) -> {
                   int lastRanking = rank1.lastKey();
                   int offset = lastRanking + rank1.get(lastRanking).size()-1;
                   if( propertyExtractor.apply(rank1.get(lastRanking).get(0))
                       ==

    propertyExtractor.apply(rank2.get(rank2.firstKey()).get(0))){
                         rank1.get(lastRanking).addAll(rank2.get(rank2.firstKey()));
                         rank2.remove(rank2.firstKey());
                       }
                       rank2.forEach((r,items) -> {rank1.put(offset+r, items);} );
                }
         )
      );
    }
</code>```

This collector factory method can be used e.g. as:

```<code>SortedMap<Integer,List<String>> ranking =
        words.collect(rankingCollector(String::length,reverseOrder()));
</code>```

Printing the ranking

Once the ranking has been computed and stored in the map, it can be printed,  typically for debug purposes.

Here are a few possible options for printing the ranking on the console.

Printer Consumer

Using a consumer object that takes the ranking, format the entries
and print them.
The following code reports a factory method the returns
such a consumer:

```<code>static <T,V> Consumer<Map<Integer,List<T>>>
rankPrinter(Function<T,V> propertyExtractor){
      return ranking ->
       ranking.entrySet().stream()
       .map( e -> e.getValue().stream().map(
                   v -> e.getKey() + " - " + v
                       + " (" + propertyExtractor.apply(v) + ")" ) )
        .flatMap(Function.identity())
        .forEach(System.out::println);
}
</code>```

Collator Function

Using a function that transform the ranking map into
a string consisting in the concatenation of the items.

```<code>Function<String,Integer> propertyExtractor = String::length;
</code>```0

The above method can be used as follows:

```<code>Function<String,Integer> propertyExtractor = String::length;
</code>```1

Ranking Map class

As an alternative, is is possible to replace the class TreeMap
with a new class that extends it and overrides the toString()
method.

This cane be done by writing the following collector accumulator
supplier, instead of TreeMap::new:

```<code>Function<String,Integer> propertyExtractor = String::length;
</code>```2

The complete code for the generics solution is available in class
StreamRanking available on my github repo.

Body:
A common problem when processing data is to build a ranking of items
based on some property.

The ranking operation consists
in mapping the items to a set of ordinal numbers (called ranking).
In presence of ties (i.e. two items having the same ranking) several
strategies can be used, in this context we will assume the standard competition ranking (a.k.a. "1224" ranking) is used.

The question I'd like to investigate here is what is the "best" way
of doing this using the streaming API. Where best may mean, most elengant,
most efficient, simplest, etc.

Case study

Let's start with a very simple example: a stream of words (i.e. Strings)
out of which a ranking by decreasing lengths should be created.
If we take the first paragraph of this document, i.e.

A common problem when processing data is to build
a ranking of itemsbased on some property

we would get the following ranking (by inverse lengths)
should be obtained:

1 - processing (10)
2 - property (8)
3 - problem (7)
3 - ranking (7)
5 - common (6)
6 - build (5)
6 - items (5)
6 - based (5)
9 - when (4)
9 - data (4)
9 - some (4)
12 - is (2)
12 - to (2)
12 - of (2)
12 - on (2)
16 - A (1)
16 - a (1)

When two items share the same ranking property value, they are assigned the same ranking.

Questions

The main question here is:

what stream API construct do you used to compute the ranking and how
  you organize your code?

A second related question is

how you represent the result of the ranking computation?

Body:
The two questions are addressed one after the other

ranking representation

ranking procedure

Ranking representation

The typical ranking, as shown above, is a list of items preceded by their relative ranking value.

There are, at least, two possible implementations for the return value
of a ranking.

Option 1: List<Rank>

A possible internal representation of the ranking could be a list of
elements containing both the ranking value and the item. For instance
we could define a class:

public class Rank<T> {
  protected int ranking;
  protected T item;
  protected Rank(int r, T i) { ranking=t; item=i; }
  public int getRanking() { return ranking; }
  public T getItem() { return item; }
  static <T> Rank<T> factory(int ranking, T item) {
      return new Rank<T>(ranking,item);
  }
}

Or, with a somewhat more esotheric code:

public interface Rank<T> {
      int getRanking();
      T getItem();
      static <T> Rank<T> factory(int ranking, T item) {
          return new Rank<T>(){
               public int getRanking() { return ranking; }
               public T getItem() { return item; }
          };}
}

The resulting ranking will be returned as a List<Rank>.
The list must be returned sorted by descending ranking and processed in that order.

A potential disadvantage of such solution is the need for a new ad-hoc class or interface (i.e. Rank).

Option 2: SortedMap<Integer,List<T>>

An alternative solution that uses only predefined standard classes and intefaces is based on a map.

The keys of the map correspond to the ranking values, while the values of the map consist in lists that contain the items sharing that ranking.

The return type of the ranking would be a SortedMap<T,List<T>>.
The sorted map will be implicitly sorted and can be traversed according to the natural order of the key.

This latter solution seems preferable because it does not require any new class and can be better understood.

Ranking Procedure

The ranking computation procedure can be implemented in different ways.
Here two approaches are examined.

In all cases we need to have a function that serves the purpose
of extracting the ranking property:

Function<String,Integer> propertyExtractor = String::length;

Typically, the property type should be comparable, though to be more general (e.g. to sort strings in decreasing order) the property comparator can be defined:

Comparator<Integer> propertyComparator = reverseOrder();

The two approaches are illustrated, referring to the case study described above, using a words stream as a starting point:

String paragraph = "A common problem when processing data is to build  a ranking of items based on some property";
Stream<String> words = Stream.of(paragraph.split(" "));

Sorting by ranking property

Basic procedure

An initial naive version of the procedure can be defined using a supporting map data structure upon which the stream operations work by means of side effects:

SortedMap<Integer,List<String>> ranking = new TreeMap<>();

The procedure is as follows:

Sort the elements of the stream

words.sorted(comparing(propetyExtractor,propertyComparator))

Assign the ranking, starting with 1 and incrementing it
any time the property changes. The ranking has to be incremented
by the number of items that shared the current ranking.

.forEach( item -> {
    Integer property = propertyExtractor.apply(item);
    if(ranking.isEmpty()){
        ranking.put(1,new LinkedList<String>());
    }else{
        Integer rank = ranking.lastKey();
        List<String> items = ranking.get(rank);
        if(! property.equals(propertyExtractor.apply(items.get(0)))) {
            ranking.put(rank+items.size(), new LinkedList<String>());
        }
    }
    ranking.get(ranking.lastKey()).add(item);
});

The above code works as follows:

The initial sequence of items is unsorted:

{"DD","BBB","F","CCC","AAAA","EE"}

Step 1 sorts the item using the propertyExtractor and the relative propertyComparator, i.e. by string length:

{"AAAA","BBB","CCC","DD","EE","F"}

then for each element (in order) a new entry in the map is added
any time the lenght of the new element differs from the previous
element lenght

When "AAAA" is processed (first item) a new entry is added to
the map with key (i.e. ranking) = 1:

ranking : {1=["AAAA"]}

As the second item "BBB" is processed, since its lenght (3)
is different from the last element length (4, the lenght of "AAAA")
a new entry is added with un updated ranking value:

ranking : {1=["AAAA"],2=["BBB"]}

As the third item "CCC" is processed, since its lenght (3)
is equal to the last element length, the item is added
to the entry list

ranking : {1=["AAAA"],2=["BBB","CCC"]}

etc.

Usage of collector

A more functional-style version can be defined by using a collector that encapsulates the data structure where the results are accumulated.
In practice we can write a single stream expression that returns the ranking map:

SortedMap<Integer,List<String>> ranking =
words.sorted(comparing(propertyExtractor,propertyComparator))
     .collect(TreeMap::new, // supplier

             (rank, item) -> {  // accumulator
                 Integer property = propertyExtractor.apply(item);
                 if(rank.isEmpty()){
                     rank.put(1,new LinkedList<String>());
                 }else{
                     Integer r = rank.lastKey();
                     List<String> items = rank.get(r);
                     Integer prevProp = propertyExtractor.apply(items.get(0))
                     if(! property.equals(prevProp)) {
                         rank.put(r+items.size(), new LinkedList<String>());
                     }
                 }
                 rank.get(rank.lastKey()).add(item);
             },

             (rank1,rank2) -> { // combiner
                 \\...
             }
     );

Combining results

The combiner method that is left undefiened in the above code deserves some additional reflections.

The functional interface is involved when the collection is performed in parallel; it is used to combine two partial results of the accumulation into a single one. In this case, it has to implement the interface BiConsumer<R,R> and it is supposed to combine the two accumulated rankings - rank1 and rank2 - into the first one.

A possible implementation of the supplier is:

BiConsumer<SortedMap<Integer,List<String>>,
             SortedMap<Integer,List<String>>> combiner =
(rank1,rank2) -> {
        int lastRanking = rank1.lastKey();
        int offset = lastRanking + rank1.get(lastRanking).size()-1;
        if( propertyExtractor.apply(rank1.get(lastRanking).get(0))
            == propertyExtractor.apply(rank2.get(rank2.firstKey()).get(0)) ){
            rank1.get(lastRanking).addAll(rank2.get(rank2.firstKey()));
            rank2.remove(rank2.firstKey());
        }
        rank2.forEach((r,items) -> {rank1.put(offset+r, items);} );
}

The collector has no declared properties, so the elements will be processed in order and then composed in order. E.g. the sorted list of items is divided into two parts, then the first part is processed through with one copy of the collector producing as result the map rank1; in parallel, the second part is processed giving as result rank2.

Let us suppose the streams are processed in parallel, in two concurent
execution of the collect operations:

the initial sorted stream (result of the sorted() operation is
divided into two stream, maintaining the orded

sub-stream 1: {"AAAA","BBB","CCC"}

sub-stream 2: {"DD","EE","F"}

two distinct collectors operate in parallel, on each sub-stream
the result are two maps contain the partial ranking of each sub-stream:

rank1 = {1=["AAAA"],2=["BBB","CCC"]}

rank2 = {1=["DD","EE"],3=["F"]}

The combiner operation should merge rank2 into rank1, in practice
each entry of the rank2 operation should be added to rank1 with its
key updated. They keys are updated by adding an offset that is equal to
the key of the last entry plus the lenght of the last entry value list
minus one:

int lastRanking = rank1.lastKey();
int offset = lastRanking + rank1.get(lastRanking).size()-1;

In practice the entry 1=["DD","EE"] of rank2 should be turned into
4=["DD","EE"] and added to rank1.

In addition, a special case should be considered, i.e. when the items
in the last entry of rank1 and those in the first entry of rank2
share the same ranking property value. E.g. for string length:

rank1 = {1=["AAAA"],2=["BBB","CCC"]}

rank2 = {1=["DDD"],2=["EE"],3=["F"]}

When this case occurs, the items in the rank2 first entry list
must be added to this in the last rank1 entry list, and then the
first entry removed.
That is the above maps should be transformed into:

rank1 = {1=["AAAA"],2=["BBB","CCC","DDD"]}

rank2 = {~~1=["DDD"],~~2=["EE"],3=["F"]}

Then the entries of rank2 can be updated and added to rank1 as
described above.

Grouping by ranking property

Basic procedure

As for the sorted list version, an initial naive version of the procedure can be defined using a supporting map data structure upon which the stream operations work by means of side effects:

SortedMap<Integer,List<String>> ranking = new TreeMap<>();

The naive procedure is as follows:

group the items by their property in a sorted map

words.collect(groupingBy(propertyExtractor,
                        ()->new TreeMap<>(propertyComparator),toList()))

for each entry in the above map compute the ranking

     .forEach(
        (property,items) ->
            ranking.put(ranking.isEmpty()?1:ranking.lastKey()+
                                ranking.get(ranking.lastKey()).size(),
                        items )
             );

The above code works as follows:

The initial sequence of items is unsorted:

{"DD","BBB","F","CCC","AAAA","EE"}

Step 1 groups the item by their propertyExtractor and store them into
a sorted set whose keys are sorted through the propertyComparator, i.e.
by string length:

{4=["AAAA"],3=["BBB","CCC"],2=["DD","EE"],1=["F"]}

Step 2, creates for each entry in the intermediate map a new entry in
the result map have the ranking value as key and the same value (i.e.
the list of items) as the intermediate entry.

The ranking is computed as follows:

1 for the first entry (i.e. when the result map is still empty), or

previous ranking (ranking.lastKey()) plus number of elements
sharing the previous ranking (ranking.get(ranking.lastKey()).size()).

The result is the final ranking map:

{1=["AAAA"],2=["BBB","CCC"],4=["DD","EE"],6=["F"]}

Using a collector

The above procedure can be rewritten using a collector to avoid side effects of the operations.

Since the first step consists in a collection, we can use the predefined collector factory methdo collectingAndThen to concatenate the first collector with a function that is applied to the collector result;
such a function will perform the step 2 described above.

SortedMap<Integer,List<String>> ranking =
words.collect(
       collectingAndThen(
            groupingBy(propertyExtractor,
                         ()->new TreeMap<>(propertyComparator),
                         toList()),
            map -> map.entrySet().stream().collect(
                      TreeMap::new,
                      (rank,entry) ->
                          rank.put(rank.isEmpty()?1:rank.lastKey()+
                                        rank.get(rank.lastKey()).size(),
                                 entry.getValue() ),
                      combiner
                    )
        )
);

Since the structure of the result, i.e. the accumulator object, is the
same as the sorted stream solution, here the same combiner can be used.

Generic solutions

The above discussion and solution applied to the special case of
a stream of Strings. But the approach can be generalized using generics.

Ranking sorting function

The solution based on the sorted stream can be enclosed in a function:

static <T,V> SortedMap<Integer,List<T>>
rank(Stream<T> stream,
     Function<T,V> propertyExtractor,
     Comparator<V> propertyComparator){
  return
  stream.sorted(comparing(propertyExtractor,propertyComparator))
        .collect(TreeMap::new,
                 (rank, item) -> {
                    V property = propertyExtractor.apply(item);
                    if(rank.isEmpty()){
                      rank.put(new Integer(1),new LinkedList<T>());
                    }else{
                      Integer r = rank.lastKey();
                      List<T> items = rank.get(r);
                      if(! property.equals(propertyExtractor.apply(items.get(0)))) {
                        rank.put(r+items.size(), new LinkedList<T>());
                      }
                    }
                    rank.get(rank.lastKey()).add(item);
                },
            (rank1,rank2) -> {
                   int lastRanking = rank1.lastKey();
                   int offset = lastRanking + rank1.get(lastRanking).size()-1;
                   if( propertyExtractor.apply(rank1.get(lastRanking).get(0))
                       == propertyExtractor.apply(rank2.get(rank2.firstKey()).get(0))){
                     rank1.get(lastRanking).addAll(rank2.get(rank2.firstKey()));
                     rank2.remove(rank2.firstKey());
                   }
                   rank2.forEach((r,items) -> {rank1.put(offset+r, items);} );
            }
    );
}

The above method can be applied as:

SortedMap<Integer,List<String>> ranking =
            rank(words,String::length,reverseOrder());

Ranking grouping collector

The approach based on the grouping by property value can be
encapsulated in a collector:

static <T,V> Collector<T,?,SortedMap<Integer,List<T>>>
rankingCollector(Function<T,V> propertyExtractor,
                 Comparator<V> propertyComparator){
  return
  collectingAndThen(
    groupingBy(propertyExtractor,
               ()->new TreeMap<>(propertyComparator),
               toList()),
    map -> map.entrySet().stream().collect(
            TreeMap::new,
            (rank,entry) ->
                  rank.put(rank.isEmpty()?1:rank.lastKey()+
                             rank.get(rank.lastKey()).size(),
                           entry.getValue() ),
            (rank1,rank2) -> {
                   int lastRanking = rank1.lastKey();
                   int offset = lastRanking + rank1.get(lastRanking).size()-1;
                   if( propertyExtractor.apply(rank1.get(lastRanking).get(0))
                       ==

    propertyExtractor.apply(rank2.get(rank2.firstKey()).get(0))){
                         rank1.get(lastRanking).addAll(rank2.get(rank2.firstKey()));
                         rank2.remove(rank2.firstKey());
                       }
                       rank2.forEach((r,items) -> {rank1.put(offset+r, items);} );
                }
         )
      );
    }

This collector factory method can be used e.g. as:

SortedMap<Integer,List<String>> ranking =
        words.collect(rankingCollector(String::length,reverseOrder()));

Printing the ranking

Once the ranking has been computed and stored in the map, it can be printed,  typically for debug purposes.

Here are a few possible options for printing the ranking on the console.

Printer Consumer

Using a consumer object that takes the ranking, format the entries
and print them.
The following code reports a factory method the returns
such a consumer:

static <T,V> Consumer<Map<Integer,List<T>>>
rankPrinter(Function<T,V> propertyExtractor){
      return ranking ->
       ranking.entrySet().stream()
       .map( e -> e.getValue().stream().map(
                   v -> e.getKey() + " - " + v
                       + " (" + propertyExtractor.apply(v) + ")" ) )
        .flatMap(Function.identity())
        .forEach(System.out::println);
}

Collator Function

Using a function that transform the ranking map into
a string consisting in the concatenation of the items.

static <T,V> Function<Map<Integer,List<T>>,String>
rankCollator(Function<T,V> propertyExtractor){
  return ranking ->
        ranking.entrySet().stream()
                .map( e -> (Stream<String>)e.getValue().stream().
                        map( v -> (String)(e.getKey() + " : " + v + " (" + propertyExtractor.apply(v) + ")") ))
                        .flatMap(Function.identity())
                        .collect(joining("\n"));
    }

The above method can be used as follows:

System.out.println(rankCollator(propertyExtractor).apply(ranking));

Ranking Map class

As an alternative, is is possible to replace the class TreeMap
with a new class that extends it and overrides the toString()
method.

This cane be done by writing the following collector accumulator
supplier, instead of TreeMap::new:

()->new TreeMap<Integer,List<T>>(){
    public String toString(){
        return entrySet().stream()
                .map( e -> (Stream<String>)e.getValue().stream().map(
                            v -> e.getKey().toString() + " - " + v.toString()
                                    + " (" + propertyExtractor.apply(v) + ")" ) )
                .flatMap(Function.identity())
                .collect(joining("\n"));
    }
}

The complete code for the generics solution is available in class
StreamRanking available on my github repo.


问:
How to limit tx_news teaser and bodytext length in Backend TCA?
For limiting the maximum length of a news title, i can use this tsConfig setting:

```<code>TCEFORM.tx_news_domain_model_news.title.config.max = 70
</code>```

Is it possible to set such a limitation also for teaser and bodytext of news records? Since these are not simple input fields but textareas or RTE fields, it doesn´t seem to be that easy to limit their length. Is it possible nevertheless?

答: Look at typo3conf/ext/news/Resources/Private/Partials/List/Item.html here you can find the setting settings.cropMaxCharacters, so if you set plugin.tx_news.settings.cropMaxCharacters = 150 your text displayed with max 150 Chars.

Body:
For limiting the maximum length of a news title, i can use this tsConfig setting:

TCEFORM.tx_news_domain_model_news.title.config.max = 70

Is it possible to set such a limitation also for teaser and bodytext of news records? Since these are not simple input fields but textareas or RTE fields, it doesn´t seem to be that easy to limit their length. Is it possible nevertheless?


问:
Can I combine all Groovy sources to one script?
I have a project on Groovy, which is built with Maven. Can I somehow on build step to merge all files with a source code into a single Groovy script for delivery to the end user?</p>

答:
That is impossible. Another way is use evaluate:

```<code>evaluate(new File("../tools/Tools.groovy"))
</code>```

Body:
That is impossible. Another way is use evaluate:

evaluate(new File("../tools/Tools.groovy"))


问:
Draw rectangles on an image in Matlab
I am trying to figure out how to draw rectangles on an image in Matlab.

Once the rectangles are drawn on the image I would like to save the changes.

Thanks in advance!

答:
Without using getframe:

```<code>im=imread('face.jpg'); %Image read
rectangle('Position', [10 10 30 30] ,...
    'EdgeColor', 'r',...
    'LineWidth', 3,...
    'LineStyle','-');%rectangle properties
imshow( im, rectangle); %draw rectangle on image.
</code>```

For more detail visit this MathWorks thread :)

Title: Draw rectangles on an image in Matlab

Body:
Without using getframe:

im=imread('face.jpg'); %Image read
rectangle('Position', [10 10 30 30] ,...
    'EdgeColor', 'r',...
    'LineWidth', 3,...
    'LineStyle','-');%rectangle properties
imshow( im, rectangle); %draw rectangle on image.

For more detail visit this MathWorks thread :)


问:
Extract lines corresponding to the minimum value in the last column
I need help with extracting all the lines from the file that has minimum number in the last column, i.e 7 in in this case.

The sample file is as below:

File-1.txt

```<code>VALID_PATH :  [102, 80, 112, 109, 23, 125, 111] 7
VALID_PATH :  [102, 81, 112, 109, 23, 125, 111] 7
VALID_PATH :  [102, 112, 37, 109, 23, 125, 111] 7
VALID_PATH :  [102, 112, 37, 56, 23, 125, 111]  7
VALID_PATH :  [102, 80, 112, 37, 109, 23, 125, 111] 8
VALID_PATH :  [102, 80, 112, 37, 56, 23, 125, 111]  8
VALID_PATH :  [102, 80, 112, 109, 23, 125, 110, 111]    8
VALID_PATH :  [102, 80, 127, 6, 112, 109, 23, 125, 111] 9
VALID_PATH :  [102, 80, 127, 88, 112, 109, 23, 125, 111]    9
VALID_PATH :  [102, 80, 112, 37, 109, 23, 125, 110, 111]    9
VALID_PATH :  [102, 80, 112, 37, 56, 23, 125, 110, 111] 9
VALID_PATH :  [102, 80, 127, 6, 112, 37, 109, 23, 125, 111] 10
VALID_PATH :  [102, 80, 127, 6, 112, 37, 56, 23, 125, 111]  10
VALID_PATH :  [102, 80, 127, 6, 112, 109, 23, 125, 110, 111]    10
</code>```

Here, I want to extract all the lines that have 7, which is the least value (minimum value) in the last column and save the output into another file File-2.txt by only extracting the values enclosed in [], as shown below.

File-2.txt

```<code>102, 80, 112, 109, 23, 125, 111
102, 81, 112, 109, 23, 125, 111
102, 112, 37, 109, 23, 125, 111
102, 112, 37, 56, 23, 125, 111
</code>```

I could use awk to get the least value as "7" from the last column using the code as below:

```<code>awk 'BEGIN{getline;min=max=$NF}
NF{
    max=(max>$NF)?max:$NF
    min=(min>$NF)?$NF:min
}
END{print min,max}' File-1.txt
</code>```

and to print only the values in square brackets [] buy using the awk code as below:

```<code>awk 'NR > 1 {print $1}' RS='[' FS=']' File-1.txt
</code>```

but, I am stuck in assigning the least value obtained from first awk script, i.e. 7 in this case to extract the corresponding numbers enclosed in [], as shown in File-2.txt.

Any help in resolving this problem will be appreciated.

答:
@Asha:@try:

```<code>awk '{Q=$NF;gsub(/.*\[|\]/,"");$NF="";A[Q]=A[Q]?A[Q] ORS $0:$0;MIN=MIN<Q?(MIN?MIN:Q):Q} END{print A[MIN]}' Input_file
</code>```

Will add description shortly too.

EDIT: Following is the description on same too.

```<code>awk '{
Q=$NF;                    ##### Making last field of Input_file as NULL.
gsub(/.*\[|\]/,"");       ##### Using global substitution functionality of awk to remove everything till [ and then remove ] from the line as per your required output.
$NF="";                   ##### Nullifying the last column of each line as you don't need them in your output.
A[Q]=A[Q]?A[Q] ORS $0:$0; ##### creating an array named A whose index is Q variable(whose value is already assigned previously to last column), creating array A with index Q and concatenating it's value in itself.
MIN=MIN<Q?(MIN?MIN:Q):Q}  ##### Creating a variable named MIN(to get the minimum last value of each line) and comparing it's value to each line's last field and keeping the minimum value in it as per requirement.
END{print A[MIN]}         ##### In end block of code printing the value of array A whose index is variable MIN to print all the lines whose index is variable named MIN.
' Input_file              ##### Mentioning the Input_file here.
</code>```

Body:
I need help with extracting all the lines from the file that has minimum number in the last column, i.e 7 in in this case.

The sample file is as below:

File-1.txt

VALID_PATH :  [102, 80, 112, 109, 23, 125, 111] 7
VALID_PATH :  [102, 81, 112, 109, 23, 125, 111] 7
VALID_PATH :  [102, 112, 37, 109, 23, 125, 111] 7
VALID_PATH :  [102, 112, 37, 56, 23, 125, 111]  7
VALID_PATH :  [102, 80, 112, 37, 109, 23, 125, 111] 8
VALID_PATH :  [102, 80, 112, 37, 56, 23, 125, 111]  8
VALID_PATH :  [102, 80, 112, 109, 23, 125, 110, 111]    8
VALID_PATH :  [102, 80, 127, 6, 112, 109, 23, 125, 111] 9
VALID_PATH :  [102, 80, 127, 88, 112, 109, 23, 125, 111]    9
VALID_PATH :  [102, 80, 112, 37, 109, 23, 125, 110, 111]    9
VALID_PATH :  [102, 80, 112, 37, 56, 23, 125, 110, 111] 9
VALID_PATH :  [102, 80, 127, 6, 112, 37, 109, 23, 125, 111] 10
VALID_PATH :  [102, 80, 127, 6, 112, 37, 56, 23, 125, 111]  10
VALID_PATH :  [102, 80, 127, 6, 112, 109, 23, 125, 110, 111]    10

Here, I want to extract all the lines that have 7, which is the least value (minimum value) in the last column and save the output into another file File-2.txt by only extracting the values enclosed in [], as shown below.

File-2.txt

102, 80, 112, 109, 23, 125, 111
102, 81, 112, 109, 23, 125, 111
102, 112, 37, 109, 23, 125, 111
102, 112, 37, 56, 23, 125, 111

I could use awk to get the least value as "7" from the last column using the code as below:

awk 'BEGIN{getline;min=max=$NF}
NF{
    max=(max>$NF)?max:$NF
    min=(min>$NF)?$NF:min
}
END{print min,max}' File-1.txt

and to print only the values in square brackets [] buy using the awk code as below:

awk 'NR > 1 {print $1}' RS='[' FS=']' File-1.txt

but, I am stuck in assigning the least value obtained from first awk script, i.e. 7 in this case to extract the corresponding numbers enclosed in [], as shown in File-2.txt.

Any help in resolving this problem will be appreciated.

Body:
@Asha:@try:

awk '{Q=$NF;gsub(/.*\[|\]/,"");$NF="";A[Q]=A[Q]?A[Q] ORS $0:$0;MIN=MIN<Q?(MIN?MIN:Q):Q} END{print A[MIN]}' Input_file

Will add description shortly too.

EDIT: Following is the description on same too.

awk '{
Q=$NF;                    ##### Making last field of Input_file as NULL.
gsub(/.*\[|\]/,"");       ##### Using global substitution functionality of awk to remove everything till [ and then remove ] from the line as per your required output.
$NF="";                   ##### Nullifying the last column of each line as you don't need them in your output.
A[Q]=A[Q]?A[Q] ORS $0:$0; ##### creating an array named A whose index is Q variable(whose value is already assigned previously to last column), creating array A with index Q and concatenating it's value in itself.
MIN=MIN<Q?(MIN?MIN:Q):Q}  ##### Creating a variable named MIN(to get the minimum last value of each line) and comparing it's value to each line's last field and keeping the minimum value in it as per requirement.
END{print A[MIN]}         ##### In end block of code printing the value of array A whose index is variable MIN to print all the lines whose index is variable named MIN.
' Input_file              ##### Mentioning the Input_file here.


问:
How to remove observeEvent in Shiny?
I have function that show modal with one input to change name that execute function when save button is clicked and I have validation bind to input:

```<code>editNameDialog <- function(input, value, name, save) {
  showModal(modalDialog(
    textInput("modalNewName", paste("Enter", name, ":"), value),
    title = paste("Edit",  name),
    easyClose = TRUE,
    footer = div(
      modalButton("Cancel"),
      actionButton("modalSaveName", "Save", class = "btn-primary")
    )
  ))
  validName <- function() {
    nchar(input$newName) > 5
  }
  observeEvent(input$modalNewName, {
    if (validName()) {
      shinyjs::enable("modalSaveName")
    } else {
      shinyjs::disable("modalSaveName")
    }
  });

  observeEvent(input$modalSaveName, {
    save(input$modalNewName)
    removeModal()
  }, ignoreInit = TRUE, once = TRUE)
}
</code>```

I call this function like this (from server.R):

```<code>editNameDialog(input, "default value", "enter name", function(value) {
   other$name <- value
})
</code>```

it work but when I execute the function two times the observer input$modalNewName is executed two times for each keypress. How can I remove the event before adding new one?

答:
I've fixed the issue by adding validation in javascript:

```<code>function observeModalName() {
  var save = $('#modalSaveName');
  $('#modalNewName').off('keyup').on('keyup', function() {
    var self = $(this);
    if (self.val().length < 5) {
      save.disable();
      self.error({message: 'Name must be at least 5 characters long'});
    } else {
      save.enable();
      self.error('remove');
    }
  });
}
</code>```

and executed:

```<code>shinyjs::runjs("observeModalName()")
</code>```

Title: How to remove observeEvent in Shiny?

Body:
I have function that show modal with one input to change name that execute function when save button is clicked and I have validation bind to input:

editNameDialog <- function(input, value, name, save) {
  showModal(modalDialog(
    textInput("modalNewName", paste("Enter", name, ":"), value),
    title = paste("Edit",  name),
    easyClose = TRUE,
    footer = div(
      modalButton("Cancel"),
      actionButton("modalSaveName", "Save", class = "btn-primary")
    )
  ))
  validName <- function() {
    nchar(input$newName) > 5
  }
  observeEvent(input$modalNewName, {
    if (validName()) {
      shinyjs::enable("modalSaveName")
    } else {
      shinyjs::disable("modalSaveName")
    }
  });

  observeEvent(input$modalSaveName, {
    save(input$modalNewName)
    removeModal()
  }, ignoreInit = TRUE, once = TRUE)
}

I call this function like this (from server.R):

editNameDialog(input, "default value", "enter name", function(value) {
   other$name <- value
})

it work but when I execute the function two times the observer input$modalNewName is executed two times for each keypress. How can I remove the event before adding new one?

Body:
I've fixed the issue by adding validation in javascript:

function observeModalName() {
  var save = $('#modalSaveName');
  $('#modalNewName').off('keyup').on('keyup', function() {
    var self = $(this);
    if (self.val().length < 5) {
      save.disable();
      self.error({message: 'Name must be at least 5 characters long'});
    } else {
      save.enable();
      self.error('remove');
    }
  });
}

and executed:

shinyjs::runjs("observeModalName()")


问:
What would be a simple regular expression for password check during signup?
What I want to do is just check when the user is signing up that whether the password entered is at least 6 characters and has no space in it. Thats pretty much it. What would be a regex that I could use in Java Pattern Matcher classes for this purpose?

Thanks for your help guys.

答:
Why do you need a regex?</p>

```<code>String str = "my pass";

if (str.length() < 6 || str.contains(" ")){

fail();
}
</code>```

Body:
Why do you need a regex?

String str = "my pass";

if (str.length() < 6 || str.contains(" ")){

fail();
}