问:
External versioning (external or external_gte)
I'm currently working on a project which has a "projection" storage implemented using Elasticsearch. I have a few questions about external versioning.

First of all in general, in documentation it is said

external_gte version type is meant for special use cases and should be used with care. If used incorrectly, it can result in loss of data
  Blockquote
  Why exactly it is so? Can you provide more details?

In my case in primary storage let's say I keep a set of entities and every single of them has a version number. And now it is possible to perform two kind of operations:

User make changes to a single entity which will internally cause version of entity be incremented. Then system schedules an operation which will create a document based on entity data and then index in Elasticsearch.

Someone from support team would like to recreate/refresh projection storage based on data kept in primary storage using bulk request. In this case version of entity might not change.

So, I thought of using external/external_gt for a first case and external_gte for second scenario. Another option is to use external_gte version type for both scenarios but I'm wondering what is a reason not to use it?

答: I think the documentation author meant that if versioning is not coordinated well in external systems , it will result in data loss. i.e , indexing with a higher version accidently after initial data load . As long as you have all systems which does indexing in control - i dont see any issues,</p>


来源: stackexchange

问:
Google sheets, if statement multiple conditions
Trying to make an if statement that will return 4 outcomes based on the contents of the cell

If the cell is "Yes", "No", "NA", "Unknown", to return 0, 1, 2, 3 respectively.

I can use  If(A1="Yes", 0,1)  but not sure how to handle the other conditions

答:
SWITCH would be a better call:

```<code>=SWITCH(A1,"Yes",0,"No",1,"N/A",2,"Unknown",3,"I'-'I")
</code>```

ContentLicense: CC BY-SA 3.0

Body:
SWITCH would be a better call:

=SWITCH(A1,"Yes",0,"No",1,"N/A",2,"Unknown",3,"I'-'I")


问:
how nodejs sent a value of a variable to angular4 component
app.js

```<code>transporter.sendMail(mailOptions, (error, info) => {
    if (error) {
        return console.log(error);
    }
    console.log('Message sent: %s', info.messageId);
    // Preview only available when sending through an Ethereal account
    console.log('Preview URL: %s', nodemailer.getTestMessageUrl(info));
    res.render('message',{msg:'email has been sent'});
});
</code>```

component.html

```<code><form #userForm="ngForm" (ngSubmit) = "onSubmit(userForm.value)">
  <div class="form-group">
    <label for="exampleInputPassword1">Name</label>
    <input type="text" class="form-control" placeholder="Enter Name" name="who" ngModel>
    <label for="exampleInputPassword1">Email</label>
    <input type="email" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" placeholder="Enter email" name="email" ngModel>
    <small id="emailHelp" class="form-text text-muted">I'll never share your email with anyone else.</small><br>
    <input type="text" class="form-control" placeholder="Type here..." name="message" ngModel>
  </div>
  <button type="submit" class="btn btn-primary">Sent Mail</button>
</form>
{{msg}}
</code>```

component.ts

```<code>export class MessageComponent implements OnInit {
  constructor( private http:Http) { }
  ngOnInit() {
  }
   onSubmit = function (user) {
    console.log(user);
    //this.http.post('http://xxx/externalapi/add', user);
    let parm=JSON.stringify(user);
    console.log(parm);
    let headers = new Headers({"Content-Type": "application/json"});
    let options = new RequestOptions({headers: headers});
    this.http.post("/api/send", parm, options).subscribe(data => {
    });
  }
</code>```

I want to sent message using angular4 via email. I can sent successfully. after
  that I want to sent successful message to client from app.js. but I
  don't know how I have to do?
   I want to sent value to {msg} variable that is in my component.html page

答:
In your app.js file you don't need res.render. You aren't rendering a page. All you need to send is some quick JSON data. So, instead of res.render(). Use something like res.json() See here

Next, all you need to do is listen for the response in your component and handle it.

```<code>this.http.post("/api/send", parm, options).subscribe(data => {
  this.msg = data.message; // Or Handle however you want. You should also handle errors
});
</code>```

Body:
app.js

transporter.sendMail(mailOptions, (error, info) => {
    if (error) {
        return console.log(error);
    }
    console.log('Message sent: %s', info.messageId);
    // Preview only available when sending through an Ethereal account
    console.log('Preview URL: %s', nodemailer.getTestMessageUrl(info));
    res.render('message',{msg:'email has been sent'});
});

component.html

<form #userForm="ngForm" (ngSubmit) = "onSubmit(userForm.value)">

    Name
    <input type="text" class="form-control" placeholder="Enter Name" name="who" ngModel>
    Email
    <input type="email" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" placeholder="Enter email" name="email" ngModel>
    I'll never share your email with anyone else.

    <input type="text" class="form-control" placeholder="Type here..." name="message" ngModel>

  <button type="submit" class="btn btn-primary">Sent Mail</button>
</form>
{{msg}}

component.ts

export class MessageComponent implements OnInit {
  constructor( private http:Http) { }
  ngOnInit() {
  }
   onSubmit = function (user) {
    console.log(user);
    //this.http.post('http://xxx/externalapi/add', user);
    let parm=JSON.stringify(user);
    console.log(parm);
    let headers = new Headers({"Content-Type": "application/json"});
    let options = new RequestOptions({headers: headers});
    this.http.post("/api/send", parm, options).subscribe(data => {
    });
  }

I want to sent message using angular4 via email. I can sent successfully. after
  that I want to sent successful message to client from app.js. but I
  don't know how I have to do?
   I want to sent value to {msg} variable that is in my component.html page

Body:
In your app.js file you don't need res.render. You aren't rendering a page. All you need to send is some quick JSON data. So, instead of res.render(). Use something like res.json() See here

Next, all you need to do is listen for the response in your component and handle it.

this.http.post("/api/send", parm, options).subscribe(data => {
  this.msg = data.message; // Or Handle however you want. You should also handle errors
});


问:
How can I avoid subscript out of bounds in building my website in R?
So I have a project in R that's a statistical math notebook. I have been adding links to the _site.yml throughout the semester. This weekend I updated R, and for some reason every time I knit .rmds within the notebook I get the following error.

Error in config$output[["html_document"]] : subscript out of bounds
  Calls:  ->  -> patch_html_document_options
  Execution halted

Exited with status 1.

I get the same error when I try building the whole website. I also tried to knit .rmds outside the notebook, and that was successful. I have searched everywhere for a similar issue but I couldn't really find anything that related, (or maybe my google searching isn't that good). In any case, it would be nice to have my .rmds knit successfully in this notebook. I have also uninstalled Rstudio and reinstalled it and that didn't work either.
Here is my _site.yml (Although I don't know it will help).

```<code>name: "math-325-notebook"
navbar:
  title: "Math 325 Notebook"
  left:
    - text: "Table of Contents"
      href: index.html
    - text: "Describing Data"
      menu:
        - text: "Graphical Summaries"
          href: GraphicalSummaries.html
        - text: "Numerical Summaries"
          href: NumericalSummaries.html
    - text: "Making Inference"
      menu:
        - text: "Making Inference"
          href: MakingInference.html
        - text: "t Tests"
          href: tTests.html
        - text: "Wilcoxon Tests"
          href: WilcoxonTests.html
        - text: "ANOVA"
          href: ANOVA.html
        - text: "Kruskal-Wallis"
          href: Kruskal.html
        - text: "Linear Regression"
          href: LinearRegression.html
        - text: "Logistic Regression"
          href: LogisticRegression.html
    - text: "R Help"
      menu:
        - text: "R Commands"
          href: RCommands.html
        - text: "R Markdown Hints"
          href: RMarkdownHints.html
    - text: "Analyses"
      menu:
        - text: "Analysis Rubric"
          href: ./Analyses/AnalysisRubric.html
        - text: "Good Example Analysis"
          href: ./Analyses/StudentHousing.html
        - text: "Poor Example Analysis"
          href: ./Analyses/StudentHousingPOOR.html
        - text: "My First Analysis"
          href: ./Analyses/StudentHousingII.html

output_dir: '.'
</code>```

Most of the posts I read about subscript out of bounds related to arrays that they were trying to get numbers out of the domain, which I don't think is related in this scenario.

答: Just so people know, I had this answered, it ended up being the rmarkdown library, there was some sort of bug in the latest version, I installed the version before it appears to be working fine in this aspect, I have another bug now elsewhere, but I think I can fix that.</p>

Body:
So I have a project in R that's a statistical math notebook. I have been adding links to the _site.yml throughout the semester. This weekend I updated R, and for some reason every time I knit .rmds within the notebook I get the following error.

Error in config$output[["html_document"]] : subscript out of bounds
  Calls:  ->  -> patch_html_document_options
  Execution halted

Exited with status 1.

I get the same error when I try building the whole website. I also tried to knit .rmds outside the notebook, and that was successful. I have searched everywhere for a similar issue but I couldn't really find anything that related, (or maybe my google searching isn't that good). In any case, it would be nice to have my .rmds knit successfully in this notebook. I have also uninstalled Rstudio and reinstalled it and that didn't work either.
Here is my _site.yml (Although I don't know it will help).

name: "math-325-notebook"
navbar:
  title: "Math 325 Notebook"
  left:
    - text: "Table of Contents"
      href: index.html
    - text: "Describing Data"
      menu:
        - text: "Graphical Summaries"
          href: GraphicalSummaries.html
        - text: "Numerical Summaries"
          href: NumericalSummaries.html
    - text: "Making Inference"
      menu:
        - text: "Making Inference"
          href: MakingInference.html
        - text: "t Tests"
          href: tTests.html
        - text: "Wilcoxon Tests"
          href: WilcoxonTests.html
        - text: "ANOVA"
          href: ANOVA.html
        - text: "Kruskal-Wallis"
          href: Kruskal.html
        - text: "Linear Regression"
          href: LinearRegression.html
        - text: "Logistic Regression"
          href: LogisticRegression.html
    - text: "R Help"
      menu:
        - text: "R Commands"
          href: RCommands.html
        - text: "R Markdown Hints"
          href: RMarkdownHints.html
    - text: "Analyses"
      menu:
        - text: "Analysis Rubric"
          href: ./Analyses/AnalysisRubric.html
        - text: "Good Example Analysis"
          href: ./Analyses/StudentHousing.html
        - text: "Poor Example Analysis"
          href: ./Analyses/StudentHousingPOOR.html
        - text: "My First Analysis"
          href: ./Analyses/StudentHousingII.html

output_dir: '.'

Most of the posts I read about subscript out of bounds related to arrays that they were trying to get numbers out of the domain, which I don't think is related in this scenario.


问:
Nested foreach of datatable to xydataseries
I have a datatable that is created from merging multiple others, data originally comes from imported excel files. I essentially have columns of values, although the amount of columns and names are unknown in advance and the first two columns are always to be ignored.

I'm trying to create an xydataseries<double, double>() for each column of my datatable where; x is an incrementing integer from 1 and y = column data. I've tried this on a click event (wpf);

```<code>    private void btn_Click(object sender, RoutedEventArgs e)
    {
        foreach (DataColumn i in dt.Columns)
        {
            var x = 1;
            var series = new XyDataSeries<double, double>();
            foreach (DataRow j in dt.Rows)
            {
                Convert.ToDouble(j);
                series.Append(x++,j);
            }
        }
    }
</code>```

But i get an error on the last line for j - cannot convert from 'System.Data.DataRow' to 'double'.

I am new to c# and programming in general, thank you for any help.

答:
The error you are seeing is the result of passing in a DataRow object as a parameter to series.Append when it is expecting a double. This is because Convert.ToDouble returns a double, meaning you have to assign the result to a new variable in order to use it. The original j variable remains unaltered. To get a double you must do:

double newDouble = Convert.ToDouble(j);

However this will error because Convert.ToDouble only works with objects which implement the IConvertible interface (which DataRow does not). Assuming that a value within the DataRow is what you are actually after, you can retrieve this value either by using the column index

double newDouble = Convert.ToDouble(j[2]);

or by column name

double newDouble = Convert.ToDouble(j["ColumnName"]);

Body:
I have a datatable that is created from merging multiple others, data originally comes from imported excel files. I essentially have columns of values, although the amount of columns and names are unknown in advance and the first two columns are always to be ignored.

I'm trying to create an xydataseries<double, double>() for each column of my datatable where; x is an incrementing integer from 1 and y = column data. I've tried this on a click event (wpf);

    private void btn_Click(object sender, RoutedEventArgs e)
    {
        foreach (DataColumn i in dt.Columns)
        {
            var x = 1;
            var series = new XyDataSeries<double, double>();
            foreach (DataRow j in dt.Rows)
            {
                Convert.ToDouble(j);
                series.Append(x++,j);
            }
        }
    }

But i get an error on the last line for j - cannot convert from 'System.Data.DataRow' to 'double'.

I am new to c# and programming in general, thank you for any help.


问:
Java: upload file to FTP problem (packets lost)
I'm trying to transfer a file from my Java application to an FTP server
the program works, the file is transferred, but when I go to open in the FTO folder, the file is corrupted, I think that packets are lost during the file transfer.  Why?  And how can I fix this?

Another question, how can I stop the while if I want to stop the file upload?

Thanks everybody!

The code inside my class:

```<code>FTPClient client = new FTPClient();
InputStream is = null;
//...
try{
 client.connect(MY_FTP_URL);
 client.login(USER, PASS);
 InputStream is = new FileInputStream(file_path);
 OutputStream os = client.storeFileStream(file_name);
 byte[] buffer = new byte[1024];
 int len;
 //I use this way to check the transfer progress
 while((len = is.read(buffer)) != -1){
  os.write(buffer, 0, len);
  os.flush();
 }
 os.close();
} catch (IOException e){
 e.printStackTrace();
} finally{
 try{
  if(is != null){
   is.close();
  }
  client.disconnect();
 } catch(IOException e){
  e.printStackTrace();
 }
}
</code>```

答:
Check out the FAQ:

Q: Why are my files corrupt after
  transfer?

A: The most common cause for this is
  when the file is transfered as ASCII
  but the contents of the file are not
  ASCII and the file should be
  transferred as BINARY. RFC 959 says
  the default transfer mode should be
  ASCII. FTPClient conforms to the
  standard. You must explicitly call
  setFileType(FTP.BINARY_FILE_TYPE); to
  request binary transfer mode after
  logging in to the FTP server.

Call setFileType(FTP.BINARY_FILE_TYPE);

ContentLicense: CC BY-SA 2.5

Body:
I'm trying to transfer a file from my Java application to an FTP server
the program works, the file is transferred, but when I go to open in the FTO folder, the file is corrupted, I think that packets are lost during the file transfer.  Why?  And how can I fix this?

Another question, how can I stop the while if I want to stop the file upload?

Thanks everybody!

The code inside my class:

FTPClient client = new FTPClient();
InputStream is = null;
//...
try{
 client.connect(MY_FTP_URL);
 client.login(USER, PASS);
 InputStream is = new FileInputStream(file_path);
 OutputStream os = client.storeFileStream(file_name);
 byte[] buffer = new byte[1024];
 int len;
 //I use this way to check the transfer progress
 while((len = is.read(buffer)) != -1){
  os.write(buffer, 0, len);
  os.flush();
 }
 os.close();
} catch (IOException e){
 e.printStackTrace();
} finally{
 try{
  if(is != null){
   is.close();
  }
  client.disconnect();
 } catch(IOException e){
  e.printStackTrace();
 }
}


问:
How to convert strings with even or odd numbers to 0 or 1?
Starting with the data of this form:

```<code>    col_1   col_2
0   a1      a6
1   a3      a7
2   a4      a2
3   a5      a8
</code>```

Where values are letters with numbers at the end. And I would like to convert values to 0 or 1 depending on the parity or oddness of the number at the end string, to data frame:

```<code>    col_1   col_2
0   1       0
1   1       1
2   0       0
3   1       0
</code>```

How I can approach this?

答:
```<code>import re
df.applymap(lambda x : int(re.findall(r'\d+',x)[0])%2)
Out[866]:
   col_1  col_2
0      1      0
1      1      1
2      0      0
3      1      0
</code>```

Body:
Starting with the data of this form:

    col_1   col_2
0   a1      a6
1   a3      a7
2   a4      a2
3   a5      a8

Where values are letters with numbers at the end. And I would like to convert values to 0 or 1 depending on the parity or oddness of the number at the end string, to data frame:

    col_1   col_2
0   1       0
1   1       1
2   0       0
3   1       0

How I can approach this?


问:
Loop through record lines method - Odoo v8
I have this method:

```<code>@api.onchange('qty', 'consumed_qty')
def _remaining_func(self):
    for qty in self.isbn:
        if self.qty or self.consumed_qty:
            self.remaining_qty = self.qty +(-self.consumed_qty)
</code>```

But I need it to loop through records of my line (One2many field), right now, if I add just one record it works just fine, but if I add two or more, it throws the Expected singleton error.

So, how can I loop with this method?

I have added the for qty in self.isbn but with no success.

This is the class where this method is declared:

```<code>class bsi_production_order_lines(models.Model):
    _name = 'bsi.production.order.lines'

    production_order = fields.Many2one('bsi.production.order', string="Production Orders")
    isbn = fields.Many2one('product.product', string="ISBN", domain="[('is_isbn', '=', True)]")
    qty = fields.Float(string="Quantity")
    consumed_qty = fields.Float(string="Consumed quantity")
    remaining_qty = fields.Float(string="Remaining quantity", compute="_remaining_func")
</code>```

Any ideas?

答:
you could try:

```<code>@api.onchange('qty', 'consumed_qty')
def _remaining_func(self):
    for s in self:
        for qty in s.isbn:
            if s.qty or s.consumed_qty:
                s.remaining_qty = s.qty +(-s.consumed_qty)
</code>```

I hope this help you.

Body:
I have this method:

@api.onchange('qty', 'consumed_qty')
def _remaining_func(self):
    for qty in self.isbn:
        if self.qty or self.consumed_qty:
            self.remaining_qty = self.qty +(-self.consumed_qty)

But I need it to loop through records of my line (One2many field), right now, if I add just one record it works just fine, but if I add two or more, it throws the Expected singleton error.

So, how can I loop with this method?

I have added the for qty in self.isbn but with no success.

This is the class where this method is declared:

class bsi_production_order_lines(models.Model):
    _name = 'bsi.production.order.lines'

    production_order = fields.Many2one('bsi.production.order', string="Production Orders")
    isbn = fields.Many2one('product.product', string="ISBN", domain="[('is_isbn', '=', True)]")
    qty = fields.Float(string="Quantity")
    consumed_qty = fields.Float(string="Consumed quantity")
    remaining_qty = fields.Float(string="Remaining quantity", compute="_remaining_func")

Any ideas?

Body:
you could try:

@api.onchange('qty', 'consumed_qty')
def _remaining_func(self):
    for s in self:
        for qty in s.isbn:
            if s.qty or s.consumed_qty:
                s.remaining_qty = s.qty +(-s.consumed_qty)

I hope this help you.


问:
Gulp gives this error "events.js: 141 throw er; // Unhandled 'error' event"
When I run the command gulp, I get the following error.
I am using Elementary Loki and Node 4.2.6. All the other commands are wroking fine:

npm install

bower install

gulp build

anshul@anshul-HP-Notebook:~/Downloads/fivevolts$ gulp
[16:05:40] Using gulpfile ~/Downloads/fivevolts/gulpfile.js
[16:05:40] Starting 'usemin'...
[16:05:40] Starting 'copy-bower_fonts'...
[16:05:40] Starting 'custom-images'...
[16:05:40] Starting 'custom-js'...
[16:05:40] Starting 'custom-less'...
[16:05:40] Starting 'custom-templates'...
[16:05:40] Starting 'webserver'...
[16:05:41] Finished 'webserver' after 139 ms
[16:05:41] Starting 'livereload'...
[16:05:41] Finished 'livereload' after 12 ms
[16:05:41] Starting 'watch'...
[16:05:41] 'watch' errored after 10 ms
[16:05:41] Error: watch /home/anshul/Downloads/fivevolts/src/img/ ENOSPC
    at exports._errnoException (util.js:870:11)
    at FSWatcher.start (fs.js:1234:19)
    at Object.fs.watch (fs.js:1262:11)
    at Gaze._watchDir (/home/anshul/Downloads/fivevolts/node_modules/gaze/lib/gaze.js:289:30)
    at /home/anshul/Downloads/fivevolts/node_modules/gaze/lib/gaze.js:358:10
    at iterate (/home/anshul/Downloads/fivevolts/node_modules/gaze/lib/helper.js:52:5)
    at Object.forEachSeries (/home/anshul/Downloads/fivevolts/node_modules/gaze/lib/helper.js:66:3)
    at Gaze._initWatched (/home/anshul/Downloads/fivevolts/node_modules/gaze/lib/gaze.js:354:10)
    at Gaze.add (/home/anshul/Downloads/fivevolts/node_modules/gaze/lib/gaze.js:177:8)
    at new Gaze (/home/anshul/Downloads/fivevolts/node_modules/gaze/lib/gaze.js:74:10)
[16:05:41] Server started http://localhost:8888
[16:05:41] LiveReload started on port 35729
[16:05:41] Finished 'custom-less' after 201 ms
events.js:141
      throw er; // Unhandled 'error' event
      ^

Error: watch /home/anshul/Downloads/fivevolts/dist ENOSPC
    at exports._errnoException (util.js:870:11)
    at FSWatcher.start (fs.js:1234:19)
    at Object.fs.watch (fs.js:1262:11)
    at createFsWatchInstance (/home/anshul/Downloads/fivevolts/node_modules/chokidar/lib/nodefs-handler.js:37:15)
    at setFsWatchListener (/home/anshul/Downloads/fivevolts/node_modules/chokidar/lib/nodefs-handler.js:80:15)
    at FSWatcher.NodeFsHandler._watchWithNodeFs (/home/anshul/Downloads/fivevolts/node_modules/chokidar/lib/nodefs-handler.js:228:14)
    at FSWatcher.NodeFsHandler._handleDir (/home/anshul/Downloads/fivevolts/node_modules/chokidar/lib/nodefs-handler.js:407:19)
    at FSWatcher.<anonymous> (/home/anshul/Downloads/fivevolts/node_modules/chokidar/lib/nodefs-handler.js:455:19)
    at FSWatcher.<anonymous> (/home/anshul/Downloads/fivevolts/node_modules/chokidar/lib/nodefs-handler.js:460:16)
    at FSReqWrap.oncomplete (fs.js:82:15)
```

I don't think the error is in the code, as I tried to run gulp on some other project codes that were working fine earlier, are now getting the same error.

答: This happens when multiple applications trying to access the same port, Its always FIFO. Check your gulp toolkit port and try again.</p>

Body:
When I run the command gulp, I get the following error.
I am using Elementary Loki and Node 4.2.6. All the other commands are wroking fine:

npm install

bower install

gulp build

anshul@anshul-HP-Notebook:~/Downloads/fivevolts$ gulp
[16:05:40] Using gulpfile ~/Downloads/fivevolts/gulpfile.js
[16:05:40] Starting 'usemin'...
[16:05:40] Starting 'copy-bower_fonts'...
[16:05:40] Starting 'custom-images'...
[16:05:40] Starting 'custom-js'...
[16:05:40] Starting 'custom-less'...
[16:05:40] Starting 'custom-templates'...
[16:05:40] Starting 'webserver'...
[16:05:41] Finished 'webserver' after 139 ms
[16:05:41] Starting 'livereload'...
[16:05:41] Finished 'livereload' after 12 ms
[16:05:41] Starting 'watch'...
[16:05:41] 'watch' errored after 10 ms
[16:05:41] Error: watch /home/anshul/Downloads/fivevolts/src/img/ ENOSPC
    at exports._errnoException (util.js:870:11)
    at FSWatcher.start (fs.js:1234:19)
    at Object.fs.watch (fs.js:1262:11)
    at Gaze._watchDir (/home/anshul/Downloads/fivevolts/node_modules/gaze/lib/gaze.js:289:30)
    at /home/anshul/Downloads/fivevolts/node_modules/gaze/lib/gaze.js:358:10
    at iterate (/home/anshul/Downloads/fivevolts/node_modules/gaze/lib/helper.js:52:5)
    at Object.forEachSeries (/home/anshul/Downloads/fivevolts/node_modules/gaze/lib/helper.js:66:3)
    at Gaze._initWatched (/home/anshul/Downloads/fivevolts/node_modules/gaze/lib/gaze.js:354:10)
    at Gaze.add (/home/anshul/Downloads/fivevolts/node_modules/gaze/lib/gaze.js:177:8)
    at new Gaze (/home/anshul/Downloads/fivevolts/node_modules/gaze/lib/gaze.js:74:10)
[16:05:41] Server started http://localhost:8888
[16:05:41] LiveReload started on port 35729
[16:05:41] Finished 'custom-less' after 201 ms
events.js:141
      throw er; // Unhandled 'error' event
      ^

Error: watch /home/anshul/Downloads/fivevolts/dist ENOSPC
    at exports._errnoException (util.js:870:11)
    at FSWatcher.start (fs.js:1234:19)
    at Object.fs.watch (fs.js:1262:11)
    at createFsWatchInstance (/home/anshul/Downloads/fivevolts/node_modules/chokidar/lib/nodefs-handler.js:37:15)
    at setFsWatchListener (/home/anshul/Downloads/fivevolts/node_modules/chokidar/lib/nodefs-handler.js:80:15)
    at FSWatcher.NodeFsHandler._watchWithNodeFs (/home/anshul/Downloads/fivevolts/node_modules/chokidar/lib/nodefs-handler.js:228:14)
    at FSWatcher.NodeFsHandler._handleDir (/home/anshul/Downloads/fivevolts/node_modules/chokidar/lib/nodefs-handler.js:407:19)
    at FSWatcher.<anonymous> (/home/anshul/Downloads/fivevolts/node_modules/chokidar/lib/nodefs-handler.js:455:19)
    at FSWatcher.<anonymous> (/home/anshul/Downloads/fivevolts/node_modules/chokidar/lib/nodefs-handler.js:460:16)
    at FSReqWrap.oncomplete (fs.js:82:15)

I don't think the error is in the code, as I tried to run gulp on some other project codes that were working fine earlier, are now getting the same error.


问:
Get the type name
How i can get full right name of generic type?

For example:
This code

```<code>typeof(List<string>).Name
</code>```

return

List`1

instead of

```<code>List<string>
</code>```

How to get a right name?

```<code>typeof(List<string>).ToString()
</code>```

returns System.Collections.Generic.List`1[System.String] but i want to get initial name:

```<code>List<string>
</code>```

Is it real?

答:
I had problems with the other answers in some instances, i.e. with arrays, so I ended up writing yet another one. I don't use the text from Type.Name or similar except to get the plain name of the types, because I don't know if the format is guaranteed to be the same across different .Net versions or with other implementations of the libraries (I assume it isn't).

```<code>/// <summary>
/// For the given type, returns its representation in C# code.
/// </summary>
/// <param name="type">The type.</param>
/// <param name="genericArgs">Used internally, ignore.</param>
/// <param name="arrayBrackets">Used internally, ignore.</param>
/// <returns>The representation of the type in C# code.</returns>

public static string GetTypeCSharpRepresentation(Type type, Stack<Type> genericArgs = null, StringBuilder arrayBrackets = null)
{
    StringBuilder code = new StringBuilder();
    Type declaringType = type.DeclaringType;

    bool arrayBracketsWasNull = arrayBrackets == null;

    if (genericArgs == null)
        genericArgs = new Stack<Type>(type.GetGenericArguments());

    int currentTypeGenericArgsCount = genericArgs.Count;
    if (declaringType != null)
        currentTypeGenericArgsCount -= declaringType.GetGenericArguments().Length;

    Type[] currentTypeGenericArgs = new Type[currentTypeGenericArgsCount];
    for (int i = currentTypeGenericArgsCount - 1; i >= 0; i--)
        currentTypeGenericArgs[i] = genericArgs.Pop();

    if (declaringType != null)
        code.Append(GetTypeCSharpRepresentation(declaringType, genericArgs)).Append('.');

    if (type.IsArray)
    {
        if (arrayBrackets == null)
            arrayBrackets = new StringBuilder();

        arrayBrackets.Append('[');
        arrayBrackets.Append(',', type.GetArrayRank() - 1);
        arrayBrackets.Append(']');

        Type elementType = type.GetElementType();
        code.Insert(0, GetTypeCSharpRepresentation(elementType, arrayBrackets : arrayBrackets));
    }
    else
    {
        code.Append(new string(type.Name.TakeWhile(c => char.IsLetterOrDigit(c) || c == '_').ToArray()));

        if (currentTypeGenericArgsCount > 0)
        {
            code.Append('<');
            for (int i = 0;  i < currentTypeGenericArgsCount;  i++)
            {
                code.Append(GetTypeCSharpRepresentation(currentTypeGenericArgs[i]));
                if (i < currentTypeGenericArgsCount - 1)
                    code.Append(',');
            }
            code.Append('>');
        }

        if (declaringType == null  &&  !string.IsNullOrEmpty(type.Namespace))
        {
            code.Insert(0, '.').Insert(0, type.Namespace);
        }
    }

    if (arrayBracketsWasNull  &&  arrayBrackets != null)
        code.Append(arrayBrackets.ToString());

    return code.ToString();
}
</code>```

I have tested it with crazy types like this, and so far it has worked perfectly:

```<code>class C
{
    public class D<D1, D2>
    {
        public class E
        {
            public class K<R1, R2, R3>
            {
                public class P<P1>
                {
                    public struct Q
                    {
                    }
                }
            }
        }
    }
}

type = typeof(List<Dictionary<string[], C.D<byte, short[,]>.E.K<List<int>[,][], Action<List<long[][][,]>[], double[][,]>, float>.P<string>.Q>>[][,][,,,][][,,]);

// Returns "System.Collections.Generic.List<System.Collections.Generic.Dictionary<System.String[],Test.Program.C.D<System.Byte,System.Int16[,]>.E.K<System.Collections.Generic.List<System.Int32>[,][],System.Action<System.Collections.Generic.List<System.Int64[][][,]>[],System.Double[][,]>,System.Single>.P<System.String>.Q>>[][,][,,,][][,,]":
GetTypeCSharpRepresentation(type);
</code>```

There may still be some gotchas I didn't think about, but there's a known one: to retrieve the names, I only get characters that meet the condition char.IsLetterOrDigit(c) || c == '_' until one that doesn't is found, so any names of types that use allowed characters that don't meet the condition will fail.

Title: Get the type name

Body:
How i can get full right name of generic type?

For example:
This code

typeof(List<string>).Name

return

List`1

instead of

List<string>

How to get a right name?

typeof(List<string>).ToString()

returns System.Collections.Generic.List`1[System.String] but i want to get initial name:

List<string>

Is it real?

Body:
I had problems with the other answers in some instances, i.e. with arrays, so I ended up writing yet another one. I don't use the text from Type.Name or similar except to get the plain name of the types, because I don't know if the format is guaranteed to be the same across different .Net versions or with other implementations of the libraries (I assume it isn't).

/// <summary>
/// For the given type, returns its representation in C# code.
/// </summary>
/// <param name="type">The type.</param>
/// <param name="genericArgs">Used internally, ignore.</param>
/// <param name="arrayBrackets">Used internally, ignore.</param>
/// <returns>The representation of the type in C# code.</returns>

public static string GetTypeCSharpRepresentation(Type type, Stack<Type> genericArgs = null, StringBuilder arrayBrackets = null)
{
    StringBuilder code = new StringBuilder();
    Type declaringType = type.DeclaringType;

    bool arrayBracketsWasNull = arrayBrackets == null;

    if (genericArgs == null)
        genericArgs = new Stack<Type>(type.GetGenericArguments());

    int currentTypeGenericArgsCount = genericArgs.Count;
    if (declaringType != null)
        currentTypeGenericArgsCount -= declaringType.GetGenericArguments().Length;

    Type[] currentTypeGenericArgs = new Type[currentTypeGenericArgsCount];
    for (int i = currentTypeGenericArgsCount - 1; i >= 0; i--)
        currentTypeGenericArgs[i] = genericArgs.Pop();

    if (declaringType != null)
        code.Append(GetTypeCSharpRepresentation(declaringType, genericArgs)).Append('.');

    if (type.IsArray)
    {
        if (arrayBrackets == null)
            arrayBrackets = new StringBuilder();

        arrayBrackets.Append('[');
        arrayBrackets.Append(',', type.GetArrayRank() - 1);
        arrayBrackets.Append(']');

        Type elementType = type.GetElementType();
        code.Insert(0, GetTypeCSharpRepresentation(elementType, arrayBrackets : arrayBrackets));
    }
    else
    {
        code.Append(new string(type.Name.TakeWhile(c => char.IsLetterOrDigit(c) || c == '_').ToArray()));

        if (currentTypeGenericArgsCount > 0)
        {
            code.Append('<');
            for (int i = 0;  i < currentTypeGenericArgsCount;  i++)
            {
                code.Append(GetTypeCSharpRepresentation(currentTypeGenericArgs[i]));
                if (i < currentTypeGenericArgsCount - 1)
                    code.Append(',');
            }
            code.Append('>');
        }

        if (declaringType == null  &&  !string.IsNullOrEmpty(type.Namespace))
        {
            code.Insert(0, '.').Insert(0, type.Namespace);
        }
    }

    if (arrayBracketsWasNull  &&  arrayBrackets != null)
        code.Append(arrayBrackets.ToString());

    return code.ToString();
}

I have tested it with crazy types like this, and so far it has worked perfectly:

class C
{
    public class D<D1, D2>
    {
        public class E
        {
            public class K<R1, R2, R3>
            {
                public class P<P1>
                {
                    public struct Q
                    {
                    }
                }
            }
        }
    }
}

type = typeof(List<Dictionary<string[], C.D<byte, short[,]>.E.K<List<int>[,][], Action<List<long[][][,]>[], double[][,]>, float>.P<string>.Q>>[][,][,,,][][,,]);

// Returns "System.Collections.Generic.List<System.Collections.Generic.Dictionary<System.String[],Test.Program.C.D<System.Byte,System.Int16[,]>.E.K<System.Collections.Generic.List<System.Int32>[,][],System.Action<System.Collections.Generic.List<System.Int64[][][,]>[],System.Double[][,]>,System.Single>.P<System.String>.Q>>[][,][,,,][][,,]":
GetTypeCSharpRepresentation(type);

There may still be some gotchas I didn't think about, but there's a known one: to retrieve the names, I only get characters that meet the condition char.IsLetterOrDigit(c) || c == '_' until one that doesn't is found, so any names of types that use allowed characters that don't meet the condition will fail.


问:
Legacy SQL with datalab bigquery module
When querying an SQL module with a query written in Legacy sql, and then calling the execute() method, I get the error that we should use standard SQL.

Looking through the documentation, I see that the execute method has the argument dialect = legacy (http://googledatalab.github.io/pydatalab/datalab.bigquery.html), yet when using it, we get an error see error in this image

Is there another problem? Is legacy SQL still supported by datalab bq module? is there a way to not have to move to standard SQL?

Thanks

答:
Legacy SQL is no longer supported using the google.datalab namespace. Legacy SQL still works if you use the old datalab namespace but this option will be removed soon.

For the short term, can you try running import datalab.bigquery as bq instead of import google.datalab.bigquery as bq?

For the long term, the google.datalab namespace should be used with Standard SQL queries only.

Title: Legacy SQL with datalab bigquery module


问:
Resizing a block of text depending of its width
I have a block of text in an ePub, let’s say a poem, that should keep its configuration (line breaks). But I want the block of text to reduce or increase its size based on the width of the window, more like an image, without using @media.

Is there a CSS-only fluid font-size that will change depending of the width of its container? Can I have a block of text to behave as an image when resizing?

答:
Are you talking about something like vw ?

Here is the doc https://developer.mozilla.org/en-US/docs/Web/CSS/length

You can do somethink like

```<code>.your_selected_selected_class{
   font-size: 3vw;
}
</code>```

A bootply: https://www.bootply.com/DtGzANDZSD

Body:
Are you talking about something like vw ?

Here is the doc https://developer.mozilla.org/en-US/docs/Web/CSS/length

You can do somethink like

.your_selected_selected_class{
   font-size: 3vw;
}

A bootply: https://www.bootply.com/DtGzANDZSD


问:
how to use automapper for a ViewModel with an IEnumerable<T> property
I'm trying to follow Jimmy Bogard's advice for automapping through an actionfilter (which works great in most cases). But what if I have a custom viewmodel with a collection property that I want mapped? For example,

```<code>public class WidgetSearchViewModel
{
    public WidgetSearchOptionsViewModel Options { get; set; }
    public GenericListPagerViewModel Pager { get; set; }
    public IEnumerable<WidgetSearchResultModel> Results { get; set; }
}
</code>```

The Results property comes from the repository as an IEnumerable of domain entities, which I want to convert to WidgetSearchResultModel instances using automapper. The problem is that I will need to construct a WidgetSearchViewModel in the controller to populate the Options and Pager properties. How can I use an AutoMapper ActionFilter to populate the Results property OnActionExecuted? Is it even possible, or am I going to need to puta Mapper.Map call in the controller and bootstrap all of the mappings in my unit tests?

答:
Automapper already has build in support for mapping between any nested set that implements IEnumerable.  If you define the parent and child property mappings automapper will map the nested collections just fine.

Automapper can also handle mapping anything to anything if you are implement a CustomTypeConvertor: http://automapper.codeplex.com/wikipage?title=Custom%20Type%20Converters&referringTitle=Home

Body:
I'm trying to follow Jimmy Bogard's advice for automapping through an actionfilter (which works great in most cases). But what if I have a custom viewmodel with a collection property that I want mapped? For example,

public class WidgetSearchViewModel
{
    public WidgetSearchOptionsViewModel Options { get; set; }
    public GenericListPagerViewModel Pager { get; set; }
    public IEnumerable<WidgetSearchResultModel> Results { get; set; }
}

The Results property comes from the repository as an IEnumerable of domain entities, which I want to convert to WidgetSearchResultModel instances using automapper. The problem is that I will need to construct a WidgetSearchViewModel in the controller to populate the Options and Pager properties. How can I use an AutoMapper ActionFilter to populate the Results property OnActionExecuted? Is it even possible, or am I going to need to puta Mapper.Map call in the controller and bootstrap all of the mappings in my unit tests?


问:
How can I remove the last character of a String in Swift 4?
How do I remove the last character of a string in Swift 4? I used to use substring in earlier versions of Swift, but the substring method is deprecated.

Here's the code I have.

```<code>temp = temp.substring(to: temp.index(before: temp.endIndex))
</code>```

答:
You can use dropLast()

You can find more information on Apple documentation

Body:
How do I remove the last character of a string in Swift 4? I used to use substring in earlier versions of Swift, but the substring method is deprecated.

Here's the code I have.

temp = temp.substring(to: temp.index(before: temp.endIndex))


问:
How do I create a supplier of a class with limitations regarding constructor arguments?
I have a class called Human (accepts name(string) and height(int) in the constructor) and need too create a supplier of this class that will create an object but I want the object's name to let's say be between 5-10 characters, and the height should be between 110-250. Is it possible to do so in Java?</p>

答:
here is one approach, rejecting invalid arguments

```<code>public class Human {

    private final String name;
    private final int height;

    public Human(String name, int height) {
        validateName(name);
        validateHeight(height);
        this.height = height;
        this.name = name;
    }

    private void validateName(String name) {
        if(name==null || name.length()<5 || name.length()>10)
            throw new IllegalArgumentException("Name should be between 5-10 chars long but  "+name);
    }

    private void validateHeight(int height) {
        if(height<110 || height>250)
            throw new IllegalArgumentException("Height should be between 110-250 but "+height);
    }
}
</code>```

Note that this is a RuntimeException, variations include throwing a checked exception instead and let the client code have a workaround.  Or, perhaps have a static factory method and return a InvalidHuman object if not valid.

UPDATE

Ok, I think you want something like this

```<code>public class HumanProvider {

    private static final Random r = new Random();

    private static String vowels = "aeiou";
    private static String cons = "bcdfghjklmnpqrstvwxyz";

    private static String[] patterns = "cvc vc cv cvvc vcc".split(" ");

    private HumanProvider() {
    } // don't instantiate

    public static Human createRandom() {

        String name;
        do {
            name = getRandomString();
        } while (name.length() < 5 || name.length() > 10);

        int height = r.nextInt(251 - 110) + 110;

        return new Human(name, height);
    }

    private static String getRandomString() {
        int numSyllabels = r.nextInt(5) + 1;
        StringBuilder name = new StringBuilder();
        for (int i = 0; i < numSyllabels; i++) {
            String pattern = patterns[r.nextInt(patterns.length)];
            for (char c : pattern.toCharArray()) {
                name.append(randomChar((c == 'c') ? cons : vowels));
            }
        }
        return name.toString();
    }

    private static char randomChar(String list) {
        return list.charAt(r.nextInt(list.length()));
    }
}
</code>```

Body:
here is one approach, rejecting invalid arguments

public class Human {

    private final String name;
    private final int height;

    public Human(String name, int height) {
        validateName(name);
        validateHeight(height);
        this.height = height;
        this.name = name;
    }

    private void validateName(String name) {
        if(name==null || name.length()<5 || name.length()>10)
            throw new IllegalArgumentException("Name should be between 5-10 chars long but  "+name);
    }

    private void validateHeight(int height) {
        if(height<110 || height>250)
            throw new IllegalArgumentException("Height should be between 110-250 but "+height);
    }
}

Note that this is a RuntimeException, variations include throwing a checked exception instead and let the client code have a workaround.  Or, perhaps have a static factory method and return a InvalidHuman object if not valid.

UPDATE

Ok, I think you want something like this

public class HumanProvider {

    private static final Random r = new Random();

    private static String vowels = "aeiou";
    private static String cons = "bcdfghjklmnpqrstvwxyz";

    private static String[] patterns = "cvc vc cv cvvc vcc".split(" ");

    private HumanProvider() {
    } // don't instantiate

    public static Human createRandom() {

        String name;
        do {
            name = getRandomString();
        } while (name.length() < 5 || name.length() > 10);

        int height = r.nextInt(251 - 110) + 110;

        return new Human(name, height);
    }

    private static String getRandomString() {
        int numSyllabels = r.nextInt(5) + 1;
        StringBuilder name = new StringBuilder();
        for (int i = 0; i < numSyllabels; i++) {
            String pattern = patterns[r.nextInt(patterns.length)];
            for (char c : pattern.toCharArray()) {
                name.append(randomChar((c == 'c') ? cons : vowels));
            }
        }
        return name.toString();
    }

    private static char randomChar(String list) {
        return list.charAt(r.nextInt(list.length()));
    }
}


答:
A literal Swift 4 conversion of your code is

```<code>temp = String(temp[..<temp.index(before: temp.endIndex)])
</code>```

foo.substring(from: index) becomes foo[index...]

foo.substring(to: index) becomes foo[..<index]

and in particular cases a new String must be created from the Substring result.

but the solution in the4kmen's answer is much better.

Title: How can I remove the last character of a String in Swift 4?

Body:
A literal Swift 4 conversion of your code is

temp = String(temp[..<temp.index(before: temp.endIndex)])

foo.substring(from: index) becomes foo[index...]

foo.substring(to: index) becomes foo[..<index]

and in particular cases a new String must be created from the Substring result.

but the solution in the4kmen's answer is much better.


问:
How to deal with List properties
The list doesn't add anything when the method is called, it throws an exception.
How should it be done and is it possible to do without writing this:

```<code>public List<string> Mark = new List<string>();
</code>```

I've done like this and this gives an exception

```<code>public class Student
{
    protected List<string> _mark;

    public List<string> Mark
    {
        get { return _mark; }
        set { _mark = value; }
    }

    public void Get()
    {
        Mark.Add("Hello");
    }
}
 static void Main(string[] args)
    {
       Student a = new Student();
        a.Get();
    }
</code>```

答:
Regarding "is it possible to do without writing this" (and a new use), the answer is no, because creating a new object might not be your intention.
Consider bob in the following (contrived) example:

```<code>  List<string> jim = new List<string>();
  List<string> bob;
  //code..
  bob = jim;
  //code...
</code>```

A more realistic scenario might be a List<List<string>> where you retrieve a List<string> into a variable.

Title: How to deal with List properties

Body:
The list doesn't add anything when the method is called, it throws an exception.
How should it be done and is it possible to do without writing this:

public List<string> Mark = new List<string>();

I've done like this and this gives an exception

public class Student
{
    protected List<string> _mark;

    public List<string> Mark
    {
        get { return _mark; }
        set { _mark = value; }
    }

    public void Get()
    {
        Mark.Add("Hello");
    }
}
 static void Main(string[] args)
    {
       Student a = new Student();
        a.Get();
    }

Body:
Regarding "is it possible to do without writing this" (and a new use), the answer is no, because creating a new object might not be your intention.
Consider bob in the following (contrived) example:

  List<string> jim = new List<string>();
  List<string> bob;
  //code..
  bob = jim;
  //code...

A more realistic scenario might be a List<List<string>> where you retrieve a List<string> into a variable.


问:
ListView search not working
I am trying to use TextChangedListener to implement search functionality on my ListView. But after adding some character in EditText; the ListView goes blank. I have implemented filter method in my ArrayAdapter class.

I am getting my data from JSON.

Here's my code:

UserList.java

```<code>public class UserList extends AppCompatActivity {

private ListView listView;
private ArrayList<MyDataModel> list;
private MyArrayAdapter adapter;
private EditText search;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.user_list);

    search = (EditText) findViewById(R.id.search);

    //Array List for Binding Data from JSON to this List
    list = new ArrayList<>();

    //Binding that List to Adapter
    adapter = new MyArrayAdapter(this, list);

    //Getting List and Setting List Adapter
    listView = (ListView) findViewById(R.id.listView);
    listView.setAdapter(adapter);

    listView.setTextFilterEnabled(true);
    search.addTextChangedListener(new TextWatcher() {

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {

            String text = search.getText().toString().toLowerCase(Locale.getDefault());
            adapter.filter(text);
        }

        @Override
        public void afterTextChanged(Editable s) {
        }
    });

    //Checking Internet Connection
    if (InternetConnection.checkConnection(getApplicationContext())) {
        new GetDataTask().execute();
    } else {
        Snackbar.make(findViewById(R.id.parentLayout),"Internet Connection Not Available", Snackbar.LENGTH_LONG).show();
    }
}

//Creating Get Data Task for Getting Data From Web
class GetDataTask extends AsyncTask<Void, Void, Void> {

    ProgressDialog dialog;
    int jIndex;
    int x;

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        //Progress Dialog for User Interaction
        x=list.size();

        if(x==0)
            jIndex=0;
        else
            jIndex=x;

        dialog = new ProgressDialog(UserList.this);
        dialog.setTitle("Please Wait..."+x);
        dialog.setMessage("Retrieving Data");
        dialog.show();

    }

    @Nullable
    @Override
    protected Void doInBackground(Void... params) {

        //Getting JSON Object from Web Using okHttp
        JSONObject jsonObject = JSONParser.getDataFromWeb();

        try {

            if (jsonObject != null) {

                if(jsonObject.length() > 0) {

                    JSONArray array = jsonObject.getJSONArray(Keys.KEY_CONTACTS);

                    //Check Length of Array...
                    int lenArray = array.length();
                    if(lenArray > 0) {
                        for( ; jIndex < lenArray; jIndex++) {

                            //Creating Every time New Object and adding to List
                            MyDataModel model = new MyDataModel();

                            JSONObject innerObject = array.getJSONObject(jIndex);
                            String name = innerObject.getString(Keys.KEY_NAME);

                            model.setName(name);
                            list.add(model);
                        }
                    }
                }
            } else {

            }
        } catch (JSONException je) {
            Log.i(JSONParser.TAG, "" + je.getLocalizedMessage());
        }
        return null;
    }

    @Override
    protected void onPostExecute(Void aVoid) {
        super.onPostExecute(aVoid);
        dialog.dismiss();

        //Checking if List size if more than zero then update ListView
        if(list.size() > 0) {
            adapter.notifyDataSetChanged();

        } else {
            Snackbar.make(findViewById(R.id.parentLayout), "No Data Found", Snackbar.LENGTH_LONG).show();
        }

    }
}
}
</code>```

I have implemented the filter method in my ArrayAdapter class.

Here's my ArrayAdapter class:

MyArrayAdapter.java

```<code>public class MyArrayAdapter extends ArrayAdapter<MyDataModel> implements Filterable{

List<MyDataModel> modelList;
Context context;
private LayoutInflater mInflater;
private ArrayList<MyDataModel> arrayList;

public MyArrayAdapter(Context context, List<MyDataModel> objects) {
    super(context, 0, objects);
    this.context = context;
    this.mInflater = LayoutInflater.from(context);
    modelList = objects;

    this.arrayList = new ArrayList<MyDataModel>();
    this.arrayList.addAll(modelList);
}

@Override
public MyDataModel getItem(int position) {
    return modelList.get(position);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    final ViewHolder vh;
    if (convertView == null) {
        View view = mInflater.inflate(R.layout.layout_row_view, parent, false);
        vh = ViewHolder.create((RelativeLayout) view);
        view.setTag(vh);
    } else {
        vh = (ViewHolder) convertView.getTag();
    }

    MyDataModel item = getItem(position);

    vh.textViewName.setText(item.getName());
    return vh.rootView;
}

private static class ViewHolder {
    public final RelativeLayout rootView;

    public final TextView textViewName;

    private ViewHolder(RelativeLayout rootView, TextView textViewName) {
        this.rootView = rootView;
        this.textViewName = textViewName;
    }

    public static ViewHolder create(RelativeLayout rootView) {
        TextView textViewName = (TextView) rootView.findViewById(R.id.textViewName);
        return new ViewHolder(rootView, textViewName);
    }
}

// Filter Class
public void filter(String charText) {
    charText = charText.toLowerCase(Locale.getDefault());
    modelList.clear();
    if (charText.length() == 0) {
        modelList.addAll(arrayList);
    } else {
        for (MyDataModel wp : arrayList) {
            if (wp.getName().toLowerCase(Locale.getDefault()).contains(charText)) {
                modelList.add(wp);
            }
        }
    }
    notifyDataSetChanged();
}
</code>```

答:
Call search function from aftertTexChange

```<code>search.addTextChangedListener(new TextWatcher() {

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {

    }

    @Override
    public void afterTextChanged(Editable s) {
       // i have updated this
      String text = e.toString().toLowerCase(Locale.getDefault());
        adapter.filter(text);
    }
});
</code>```

now your search method should like this

```<code>public void filter(String charText) {
charText = charText.toLowerCase(Locale.getDefault());
modelList.clear();
// add this one here
notifyDataSetChanged();

if (charText.length() == 0) {
    modelList.addAll(arrayList);
} else {
    // change this for loop
    for (int i = 0; i< arrayList.size(); i++) {
        if (arrayList.get(i).getName().toLowerCase(Locale.getDefault()).contains(charText)) {
            modelList.add(arrayList.get(i));
        }
    }
}
notifyDataSetChanged();
}
</code>```

Title: ListView search not working

Body:
I am trying to use TextChangedListener to implement search functionality on my ListView. But after adding some character in EditText; the ListView goes blank. I have implemented filter method in my ArrayAdapter class.

I am getting my data from JSON.

Here's my code:

UserList.java

public class UserList extends AppCompatActivity {

private ListView listView;
private ArrayList<MyDataModel> list;
private MyArrayAdapter adapter;
private EditText search;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.user_list);

    search = (EditText) findViewById(R.id.search);

    //Array List for Binding Data from JSON to this List
    list = new ArrayList<>();

    //Binding that List to Adapter
    adapter = new MyArrayAdapter(this, list);

    //Getting List and Setting List Adapter
    listView = (ListView) findViewById(R.id.listView);
    listView.setAdapter(adapter);

    listView.setTextFilterEnabled(true);
    search.addTextChangedListener(new TextWatcher() {

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {

            String text = search.getText().toString().toLowerCase(Locale.getDefault());
            adapter.filter(text);
        }

        @Override
        public void afterTextChanged(Editable s) {
        }
    });

    //Checking Internet Connection
    if (InternetConnection.checkConnection(getApplicationContext())) {
        new GetDataTask().execute();
    } else {
        Snackbar.make(findViewById(R.id.parentLayout),"Internet Connection Not Available", Snackbar.LENGTH_LONG).show();
    }
}

//Creating Get Data Task for Getting Data From Web
class GetDataTask extends AsyncTask<Void, Void, Void> {

    ProgressDialog dialog;
    int jIndex;
    int x;

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        //Progress Dialog for User Interaction
        x=list.size();

        if(x==0)
            jIndex=0;
        else
            jIndex=x;

        dialog = new ProgressDialog(UserList.this);
        dialog.setTitle("Please Wait..."+x);
        dialog.setMessage("Retrieving Data");
        dialog.show();

    }

    @Nullable
    @Override
    protected Void doInBackground(Void... params) {

        //Getting JSON Object from Web Using okHttp
        JSONObject jsonObject = JSONParser.getDataFromWeb();

        try {

            if (jsonObject != null) {

                if(jsonObject.length() > 0) {

                    JSONArray array = jsonObject.getJSONArray(Keys.KEY_CONTACTS);

                    //Check Length of Array...
                    int lenArray = array.length();
                    if(lenArray > 0) {
                        for( ; jIndex < lenArray; jIndex++) {

                            //Creating Every time New Object and adding to List
                            MyDataModel model = new MyDataModel();

                            JSONObject innerObject = array.getJSONObject(jIndex);
                            String name = innerObject.getString(Keys.KEY_NAME);

                            model.setName(name);
                            list.add(model);
                        }
                    }
                }
            } else {

            }
        } catch (JSONException je) {
            Log.i(JSONParser.TAG, "" + je.getLocalizedMessage());
        }
        return null;
    }

    @Override
    protected void onPostExecute(Void aVoid) {
        super.onPostExecute(aVoid);
        dialog.dismiss();

        //Checking if List size if more than zero then update ListView
        if(list.size() > 0) {
            adapter.notifyDataSetChanged();

        } else {
            Snackbar.make(findViewById(R.id.parentLayout), "No Data Found", Snackbar.LENGTH_LONG).show();
        }

    }
}
}

I have implemented the filter method in my ArrayAdapter class.

Here's my ArrayAdapter class:

MyArrayAdapter.java

public class MyArrayAdapter extends ArrayAdapter<MyDataModel> implements Filterable{

List<MyDataModel> modelList;
Context context;
private LayoutInflater mInflater;
private ArrayList<MyDataModel> arrayList;

public MyArrayAdapter(Context context, List<MyDataModel> objects) {
    super(context, 0, objects);
    this.context = context;
    this.mInflater = LayoutInflater.from(context);
    modelList = objects;

    this.arrayList = new ArrayList<MyDataModel>();
    this.arrayList.addAll(modelList);
}

@Override
public MyDataModel getItem(int position) {
    return modelList.get(position);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    final ViewHolder vh;
    if (convertView == null) {
        View view = mInflater.inflate(R.layout.layout_row_view, parent, false);
        vh = ViewHolder.create((RelativeLayout) view);
        view.setTag(vh);
    } else {
        vh = (ViewHolder) convertView.getTag();
    }

    MyDataModel item = getItem(position);

    vh.textViewName.setText(item.getName());
    return vh.rootView;
}

private static class ViewHolder {
    public final RelativeLayout rootView;

    public final TextView textViewName;

    private ViewHolder(RelativeLayout rootView, TextView textViewName) {
        this.rootView = rootView;
        this.textViewName = textViewName;
    }

    public static ViewHolder create(RelativeLayout rootView) {
        TextView textViewName = (TextView) rootView.findViewById(R.id.textViewName);
        return new ViewHolder(rootView, textViewName);
    }
}

// Filter Class
public void filter(String charText) {
    charText = charText.toLowerCase(Locale.getDefault());
    modelList.clear();
    if (charText.length() == 0) {
        modelList.addAll(arrayList);
    } else {
        for (MyDataModel wp : arrayList) {
            if (wp.getName().toLowerCase(Locale.getDefault()).contains(charText)) {
                modelList.add(wp);
            }
        }
    }
    notifyDataSetChanged();
}

Body:
Call search function from aftertTexChange

search.addTextChangedListener(new TextWatcher() {

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {

    }

    @Override
    public void afterTextChanged(Editable s) {
       // i have updated this
      String text = e.toString().toLowerCase(Locale.getDefault());
        adapter.filter(text);
    }
});

now your search method should like this

public void filter(String charText) {
charText = charText.toLowerCase(Locale.getDefault());
modelList.clear();
// add this one here
notifyDataSetChanged();

if (charText.length() == 0) {
    modelList.addAll(arrayList);
} else {
    // change this for loop
    for (int i = 0; i< arrayList.size(); i++) {
        if (arrayList.get(i).getName().toLowerCase(Locale.getDefault()).contains(charText)) {
            modelList.add(arrayList.get(i));
        }
    }
}
notifyDataSetChanged();
}


问:
Iterating through two lists in Django templates
I want to do the below list iteration in django templates:

```<code>foo = ['foo', 'bar'];
moo = ['moo', 'loo'];

for (a, b) in zip(foo, moo):
    print a, b
</code>```

django code:

```<code>{% for a, b in zip(foo, moo) %}
  {{ a }}
  {{ b }}
{% endfor %}
</code>```

I get the below error when I try this:

```<code>File "/base/python_lib/versions/third_party/django-0.96/django/template/defaulttags.py", line 538, in do_for
    raise TemplateSyntaxError, "'for' statements should have either four or five words: %s" % token.contents
</code>```

How do I accomplish this?

答:
I built django-multiforloop to solve this problem. From the README:

With django-multiforloop installed, rendering this template

```<code>{% for x in x_list; y in y_list %}
  {{ x }}:{{ y }}
{% endfor %}
</code>```

with this context

```<code>context = {
    "x_list": ('one', 1, 'carrot'),
    "y_list": ('two', 2, 'orange')
}
</code>```

will output

```<code>one:two
1:2
carrot:orange
</code>```

ContentLicense: CC BY-SA 4.0

Body:
I want to do the below list iteration in django templates:

foo = ['foo', 'bar'];
moo = ['moo', 'loo'];

for (a, b) in zip(foo, moo):
    print a, b

django code:

{% for a, b in zip(foo, moo) %}
  {{ a }}
  {{ b }}
{% endfor %}

I get the below error when I try this:

File "/base/python_lib/versions/third_party/django-0.96/django/template/defaulttags.py", line 538, in do_for
    raise TemplateSyntaxError, "'for' statements should have either four or five words: %s" % token.contents

How do I accomplish this?

Body:
I built django-multiforloop to solve this problem. From the README:

With django-multiforloop installed, rendering this template

{% for x in x_list; y in y_list %}
  {{ x }}:{{ y }}
{% endfor %}

with this context

context = {
    "x_list": ('one', 1, 'carrot'),
    "y_list": ('two', 2, 'orange')
}

will output

one:two
1:2
carrot:orange


问:
Relative image path not working(HTML)
I cant seem to get my image to display on my webpage using a relative path. Im using the program "brackets" to do all of my editing before uploading to the webpage. Below is the relative path that i'm using and when I hover over the path the image thumbnail displays. but it still wont display on the page... am I missing anything? please and thank you.   </p>

```<code><img id="01" class ="tn leftcol" width = "150" height = "150"
src=".//Images/IMG_3604.JPG" alt="1" />
</code>```

答:
there are two slashes. this can be interpreted as a protocol. Change the src to  Images/IMG_3604.JPG

If this is being populated via a variable, check the source text or environments

Title: Relative image path not working(HTML)


问:
group array object by multiple properties
I'm trying to group the following array with objects base on the siteId:

```<code>var Details = [
   {
       "addressId": "399906",
       "extAddressId": null,
       "addressType": "ORDER_FULFILLMENT",
       "siteId": 101,
       "bankAccount": [
              {"bankAccountId": "409539","extBankAccountId":null,"primary": true},
              {"bankAccountId": "409537","extBankAccountId": null, "primary": false},
              {"bankAccountId": "399907", "extBankAccountId": null, "primary": false}
       ],
       "contactId": ["399908"],
       "extContactId": null,
       "emailForPurchaseOrders": "test@test.com",
       "emailForRemittance": "example@example.com",
       "emailLanguage": "English"
   },
   {
       "addressId": "399906",
       "extAddressId": null,
       "addressType": "LEGAL",
       "siteId": 101,
       "bankAccount": [
             {"bankAccountId": "399907", "extBankAccountId": null, "primary": false}
             {"bankAccountId": "409540","extBankAccountId":null,"primary": true},
       ],
       "contactId": [],
       "extContactId": null,
       "emailForPurchaseOrders": "example@example.com",
       "emailForRemittance": "test@test.com",
       "emailLanguage": "English"
   }
]
</code>```

To something like this:

```<code>{
   "addressId": ["399906"],
   "addressType": ["ORDER_FULFILLMENT", "LEGAL"],
   "siteId": 101,
   "bankAccount": [
        {
           "bankAccountId": "409539",
           "extBankAccountId": null,
           "primary": true
        },
        {
           "bankAccountId": "409537",
           "extBankAccountId": null,
           "primary": false
        },
        {
           "bankAccountId": "399907",
           "extBankAccountId": null,
           "primary": false
        },
        {
            "bankAccountId":"409540",
            "extBankAccountId":null,
            "primary": true
        },
    ],
    "contactId": ["399908"],
    "emailForPurchaseOrders": ["test@test.com", "example@example.com"],
    "emailForRemittance": ["example@example.com","test@test.com"],
    "emailLanguage": "English"
},
</code>```

Right now I'm trying to group it but could not get the above structure to meet my needs. so far this is what i am trying to do to achieve it. Any help be highly appreciated.

```<code>       var group_to_values = subscriptionDetail.reduce(function (obj, item) {
            obj[item.siteId] = obj[item.siteId] || [];
            obj[item.siteId].push(item);
            return obj;
        }, {});
        console.log(group_to_values);
        var groups = Object.keys(group_to_values).map(function (key) {
            return {siteId: key, details: group_to_values[key]};
        });
</code>```

I know I'm missing something but can't figure it out. Any suggestion?

答:
You could use some helper arrays for the wanted types of the target properties.

Extended with a hash table for same siteId.

var data = [{ addressId: "399906", extAddressId: null, addressType: "ORDER_FULFILLMENT", siteId: 101, bankAccount: [{ bankAccountId: "409539", extBankAccountId: null, primary: true }, { bankAccountId: "409537", extBankAccountId: null, primary: false }, { bankAccountId: "399907", extBankAccountId: null, primary: false }], contactId: ["399908"], extContactId: null, emailForPurchaseOrders: "test@test.com", emailForRemittance: "example@example.com", emailLanguage: "English" }, { addressId: "399906", extAddressId: null, addressType: "LEGAL", siteId: 101, bankAccount: [{ bankAccountId: "399907", extBankAccountId: null, primary: false }, { bankAccountId: "409540", extBankAccountId: null, primary: true }], contactId: [], extContactId: null, emailForPurchaseOrders: "example@example.com", emailForRemittance: "test@test.com", emailLanguage: "English" }, { addressId: "399906", extAddressId: null, addressType: "ORDER_FULFILLMENT", siteId: 102, bankAccount: [{ bankAccountId: "409539", extBankAccountId: null, primary: true }, { bankAccountId: "409537", extBankAccountId: null, primary: false }, { bankAccountId: "399907", extBankAccountId: null, primary: false }], contactId: ["399908"], extContactId: null, emailForPurchaseOrders: "test@test.com", emailForRemittance: "example@example.com", emailLanguage: "English" }, { addressId: "399906", extAddressId: null, addressType: "LEGAL", siteId: 102, bankAccount: [{ bankAccountId: "399907", extBankAccountId: null, primary: false }, { bankAccountId: "409540", extBankAccountId: null, primary: true }], contactId: [], extContactId: null, emailForPurchaseOrders: "example@example.com", emailForRemittance: "test@test.com", emailLanguage: "English" }],
    hash = Object.create(null),
    result = [],
    singleKeys = ['siteId', 'emailLanguage'];

data.forEach(function (o) {
    if (!hash[o.siteId]) {
        hash[o.siteId] = {};
        result.push(hash[o.siteId]);
    }
    Object.keys(o).forEach(function (k) {
        if (o[k] === null) {
            return;
        }
        if (singleKeys.indexOf(k) !== -1) {
            hash[o.siteId][k] = o[k];
            return;
        }
        hash[o.siteId][k] = hash[o.siteId][k] || [];
        if (Array.isArray(o[k])) {
            Array.prototype.push.apply(hash[o.siteId][k], o[k]);
            return;
        }
        if (hash[o.siteId][k].indexOf(o[k]) === -1) {
            hash[o.siteId][k].push(o[k]);
        }
    });
});

console.log(result);```
<pre class="snippet-code-css lang-css prettyprint-override"><code>.as-console-wrapper { max-height: 100% !important; top: 0; }</code>```

Code which prevents duplicate objects with same bankAccountId, by iterating the array for inserting objects and check if the same bankAccountId already exist. If not push the actual object to the array.

var data = [{ addressId: "399906", extAddressId: null, addressType: "ORDER_FULFILLMENT", siteId: 101, bankAccount: [{ bankAccountId: "409539", extBankAccountId: null, primary: true }, { bankAccountId: "409537", extBankAccountId: null, primary: false }, { bankAccountId: "399907", extBankAccountId: null, primary: false }], contactId: ["399908"], extContactId: null, emailForPurchaseOrders: "test@test.com", emailForRemittance: "example@example.com", emailLanguage: "English" }, { addressId: "399906", extAddressId: null, addressType: "LEGAL", siteId: 101, bankAccount: [{ bankAccountId: "399907", extBankAccountId: null, primary: false }, { bankAccountId: "409540", extBankAccountId: null, primary: true }], contactId: [], extContactId: null, emailForPurchaseOrders: "example@example.com", emailForRemittance: "test@test.com", emailLanguage: "English" }, { addressId: "399906", extAddressId: null, addressType: "ORDER_FULFILLMENT", siteId: 102, bankAccount: [{ bankAccountId: "409539", extBankAccountId: null, primary: true }, { bankAccountId: "409537", extBankAccountId: null, primary: false }, { bankAccountId: "399907", extBankAccountId: null, primary: false }], contactId: ["399908"], extContactId: null, emailForPurchaseOrders: "test@test.com", emailForRemittance: "example@example.com", emailLanguage: "English" }, { addressId: "399906", extAddressId: null, addressType: "LEGAL", siteId: 102, bankAccount: [{ bankAccountId: "399907", extBankAccountId: null, primary: false }, { bankAccountId: "409540", extBankAccountId: null, primary: true }], contactId: [], extContactId: null, emailForPurchaseOrders: "example@example.com", emailForRemittance: "test@test.com", emailLanguage: "English" }],
    hash = Object.create(null),
    result = [],
    singleKeys = ['siteId', 'emailLanguage'];

data.forEach(function (o) {
    if (!hash[o.siteId]) {
        hash[o.siteId] = {};
        result.push(hash[o.siteId]);
    }
    Object.keys(o).forEach(function (k) {
        if (o[k] === null) {
            return;
        }
        if (singleKeys.indexOf(k) !== -1) {
            hash[o.siteId][k] = o[k];
            return;
        }
        hash[o.siteId][k] = hash[o.siteId][k] || [];
        if (k === 'bankAccount') {
            o[k].forEach(function (a) {
                var found = hash[o.siteId][k].some(function (b) {
                    return a.bankAccountId === b.bankAccountId;
                });
                if (!found) {
                    hash[o.siteId][k].push(a);
                }
            });
            return;
        }
        if (Array.isArray(o[k])) {
            Array.prototype.push.apply(hash[o.siteId][k], o[k]);
            return;
        }
        if (hash[o.siteId][k].indexOf(o[k]) === -1) {
            hash[o.siteId][k].push(o[k]);
        }
    });
});

console.log(result);```
<pre class="snippet-code-css lang-css prettyprint-override"><code>.as-console-wrapper { max-height: 100% !important; top: 0; }</code>```

Body:
I'm trying to group the following array with objects base on the siteId:

var Details = [
   {
       "addressId": "399906",
       "extAddressId": null,
       "addressType": "ORDER_FULFILLMENT",
       "siteId": 101,
       "bankAccount": [
              {"bankAccountId": "409539","extBankAccountId":null,"primary": true},
              {"bankAccountId": "409537","extBankAccountId": null, "primary": false},
              {"bankAccountId": "399907", "extBankAccountId": null, "primary": false}
       ],
       "contactId": ["399908"],
       "extContactId": null,
       "emailForPurchaseOrders": "test@test.com",
       "emailForRemittance": "example@example.com",
       "emailLanguage": "English"
   },
   {
       "addressId": "399906",
       "extAddressId": null,
       "addressType": "LEGAL",
       "siteId": 101,
       "bankAccount": [
             {"bankAccountId": "399907", "extBankAccountId": null, "primary": false}
             {"bankAccountId": "409540","extBankAccountId":null,"primary": true},
       ],
       "contactId": [],
       "extContactId": null,
       "emailForPurchaseOrders": "example@example.com",
       "emailForRemittance": "test@test.com",
       "emailLanguage": "English"
   }
]

To something like this:

{
   "addressId": ["399906"],
   "addressType": ["ORDER_FULFILLMENT", "LEGAL"],
   "siteId": 101,
   "bankAccount": [
        {
           "bankAccountId": "409539",
           "extBankAccountId": null,
           "primary": true
        },
        {
           "bankAccountId": "409537",
           "extBankAccountId": null,
           "primary": false
        },
        {
           "bankAccountId": "399907",
           "extBankAccountId": null,
           "primary": false
        },
        {
            "bankAccountId":"409540",
            "extBankAccountId":null,
            "primary": true
        },
    ],
    "contactId": ["399908"],
    "emailForPurchaseOrders": ["test@test.com", "example@example.com"],
    "emailForRemittance": ["example@example.com","test@test.com"],
    "emailLanguage": "English"
},

Right now I'm trying to group it but could not get the above structure to meet my needs. so far this is what i am trying to do to achieve it. Any help be highly appreciated.

       var group_to_values = subscriptionDetail.reduce(function (obj, item) {
            obj[item.siteId] = obj[item.siteId] || [];
            obj[item.siteId].push(item);
            return obj;
        }, {});
        console.log(group_to_values);
        var groups = Object.keys(group_to_values).map(function (key) {
            return {siteId: key, details: group_to_values[key]};
        });

I know I'm missing something but can't figure it out. Any suggestion?

Body:
You could use some helper arrays for the wanted types of the target properties.

Extended with a hash table for same siteId.

var data = [{ addressId: "399906", extAddressId: null, addressType: "ORDER_FULFILLMENT", siteId: 101, bankAccount: [{ bankAccountId: "409539", extBankAccountId: null, primary: true }, { bankAccountId: "409537", extBankAccountId: null, primary: false }, { bankAccountId: "399907", extBankAccountId: null, primary: false }], contactId: ["399908"], extContactId: null, emailForPurchaseOrders: "test@test.com", emailForRemittance: "example@example.com", emailLanguage: "English" }, { addressId: "399906", extAddressId: null, addressType: "LEGAL", siteId: 101, bankAccount: [{ bankAccountId: "399907", extBankAccountId: null, primary: false }, { bankAccountId: "409540", extBankAccountId: null, primary: true }], contactId: [], extContactId: null, emailForPurchaseOrders: "example@example.com", emailForRemittance: "test@test.com", emailLanguage: "English" }, { addressId: "399906", extAddressId: null, addressType: "ORDER_FULFILLMENT", siteId: 102, bankAccount: [{ bankAccountId: "409539", extBankAccountId: null, primary: true }, { bankAccountId: "409537", extBankAccountId: null, primary: false }, { bankAccountId: "399907", extBankAccountId: null, primary: false }], contactId: ["399908"], extContactId: null, emailForPurchaseOrders: "test@test.com", emailForRemittance: "example@example.com", emailLanguage: "English" }, { addressId: "399906", extAddressId: null, addressType: "LEGAL", siteId: 102, bankAccount: [{ bankAccountId: "399907", extBankAccountId: null, primary: false }, { bankAccountId: "409540", extBankAccountId: null, primary: true }], contactId: [], extContactId: null, emailForPurchaseOrders: "example@example.com", emailForRemittance: "test@test.com", emailLanguage: "English" }],
    hash = Object.create(null),
    result = [],
    singleKeys = ['siteId', 'emailLanguage'];

data.forEach(function (o) {
    if (!hash[o.siteId]) {
        hash[o.siteId] = {};
        result.push(hash[o.siteId]);
    }
    Object.keys(o).forEach(function (k) {
        if (o[k] === null) {
            return;
        }
        if (singleKeys.indexOf(k) !== -1) {
            hash[o.siteId][k] = o[k];
            return;
        }
        hash[o.siteId][k] = hash[o.siteId][k] || [];
        if (Array.isArray(o[k])) {
            Array.prototype.push.apply(hash[o.siteId][k], o[k]);
            return;
        }
        if (hash[o.siteId][k].indexOf(o[k]) === -1) {
            hash[o.siteId][k].push(o[k]);
        }
    });
});

console.log(result);

.as-console-wrapper { max-height: 100% !important; top: 0; }

Code which prevents duplicate objects with same bankAccountId, by iterating the array for inserting objects and check if the same bankAccountId already exist. If not push the actual object to the array.

var data = [{ addressId: "399906", extAddressId: null, addressType: "ORDER_FULFILLMENT", siteId: 101, bankAccount: [{ bankAccountId: "409539", extBankAccountId: null, primary: true }, { bankAccountId: "409537", extBankAccountId: null, primary: false }, { bankAccountId: "399907", extBankAccountId: null, primary: false }], contactId: ["399908"], extContactId: null, emailForPurchaseOrders: "test@test.com", emailForRemittance: "example@example.com", emailLanguage: "English" }, { addressId: "399906", extAddressId: null, addressType: "LEGAL", siteId: 101, bankAccount: [{ bankAccountId: "399907", extBankAccountId: null, primary: false }, { bankAccountId: "409540", extBankAccountId: null, primary: true }], contactId: [], extContactId: null, emailForPurchaseOrders: "example@example.com", emailForRemittance: "test@test.com", emailLanguage: "English" }, { addressId: "399906", extAddressId: null, addressType: "ORDER_FULFILLMENT", siteId: 102, bankAccount: [{ bankAccountId: "409539", extBankAccountId: null, primary: true }, { bankAccountId: "409537", extBankAccountId: null, primary: false }, { bankAccountId: "399907", extBankAccountId: null, primary: false }], contactId: ["399908"], extContactId: null, emailForPurchaseOrders: "test@test.com", emailForRemittance: "example@example.com", emailLanguage: "English" }, { addressId: "399906", extAddressId: null, addressType: "LEGAL", siteId: 102, bankAccount: [{ bankAccountId: "399907", extBankAccountId: null, primary: false }, { bankAccountId: "409540", extBankAccountId: null, primary: true }], contactId: [], extContactId: null, emailForPurchaseOrders: "example@example.com", emailForRemittance: "test@test.com", emailLanguage: "English" }],
    hash = Object.create(null),
    result = [],
    singleKeys = ['siteId', 'emailLanguage'];

data.forEach(function (o) {
    if (!hash[o.siteId]) {
        hash[o.siteId] = {};
        result.push(hash[o.siteId]);
    }
    Object.keys(o).forEach(function (k) {
        if (o[k] === null) {
            return;
        }
        if (singleKeys.indexOf(k) !== -1) {
            hash[o.siteId][k] = o[k];
            return;
        }
        hash[o.siteId][k] = hash[o.siteId][k] || [];
        if (k === 'bankAccount') {
            o[k].forEach(function (a) {
                var found = hash[o.siteId][k].some(function (b) {
                    return a.bankAccountId === b.bankAccountId;
                });
                if (!found) {
                    hash[o.siteId][k].push(a);
                }
            });
            return;
        }
        if (Array.isArray(o[k])) {
            Array.prototype.push.apply(hash[o.siteId][k], o[k]);
            return;
        }
        if (hash[o.siteId][k].indexOf(o[k]) === -1) {
            hash[o.siteId][k].push(o[k]);
        }
    });
});

console.log(result);

.as-console-wrapper { max-height: 100% !important; top: 0; }


问:
How to log request data along with response data in http:outbound-gateway
Using spring integration, I am reading from a queue and then calling a REST service using http:outbound-gateway. The code works fine. But I want to relate the logs such that for a given request key field , so and so response is received. Otherwise, it is very difficult to pinpoint for which request the response is received, when there are thousands of messages flowing through the queue.

My JSON request for the service call is as follows:
{"ID":"123","status":"A"}

my JSON Response from the service call is as follows:
{"transactionStatus":"Success"}

I want to do logging such that "ID:123" has got a reponse transactionStatus as "Success".
Please help me with the code how I can achieve this. Please let me know if you need further details.
Thanks in advance.

```<code><int:object-to-json-transformer input-channel = "gcmRequestChannel" output-channel="RESTSrvcChannel"></int:object-to-json-transformer>

<int:header-enricher id = "restenricher" input-channel = "RESTSrvcChannel" output-channel = "RESTSrvcChannel2">
    <int:header name="contentType" value="application/json"/>
    <int:header name="SPApikey" value="${throttler.SPApikey}" />
</int:header-enricher>
 <http:outbound-gateway id="gcmrestHttpOutboundGateway" request-channel="RESTSrvcChannel2" reply-channel="nullChannel"
                       extract-request-payload="true"
                       url="${throttler.url}"
                       header-mapper="headerMapper"
                       http-method="POST"
                       expected-response-type="java.lang.String"
                       >

</http:outbound-gateway>
<beans:bean id="headerMapper"
    class="org.springframework.integration.http.support.DefaultHttpHeaderMapper">
    <beans:property name="inboundHeaderNames" value="*" />
    <beans:property name="outboundHeaderNames" value="HTTP_REQUEST_HEADERS,SPApikey" />
    <beans:property name="userDefinedHeaderPrefix" value="" />
</beans:bean>
</code>```

答:
Since Spring Integration deals with the Message object in its components and via channels in between, there is a nice solution like supply your important information into the headers and they will be available in the replyMessage for your logging purpose:

```<code><header-enricher>
    <header name="originalPayload" expression="payload"/>
</header-enricher>
</code>```

Body:
Using spring integration, I am reading from a queue and then calling a REST service using http:outbound-gateway. The code works fine. But I want to relate the logs such that for a given request key field , so and so response is received. Otherwise, it is very difficult to pinpoint for which request the response is received, when there are thousands of messages flowing through the queue.

My JSON request for the service call is as follows:
{"ID":"123","status":"A"}

my JSON Response from the service call is as follows:
{"transactionStatus":"Success"}

I want to do logging such that "ID:123" has got a reponse transactionStatus as "Success".
Please help me with the code how I can achieve this. Please let me know if you need further details.
Thanks in advance.

<int:object-to-json-transformer input-channel = "gcmRequestChannel" output-channel="RESTSrvcChannel"></int:object-to-json-transformer>

<int:header-enricher id = "restenricher" input-channel = "RESTSrvcChannel" output-channel = "RESTSrvcChannel2">
    <int:header name="contentType" value="application/json"/>
    <int:header name="SPApikey" value="${throttler.SPApikey}" />
</int:header-enricher>
 <http:outbound-gateway id="gcmrestHttpOutboundGateway" request-channel="RESTSrvcChannel2" reply-channel="nullChannel"
                       extract-request-payload="true"
                       url="${throttler.url}"
                       header-mapper="headerMapper"
                       http-method="POST"
                       expected-response-type="java.lang.String"
                       >

</http:outbound-gateway>
<beans:bean id="headerMapper"
    class="org.springframework.integration.http.support.DefaultHttpHeaderMapper">
    <beans:property name="inboundHeaderNames" value="*" />
    <beans:property name="outboundHeaderNames" value="HTTP_REQUEST_HEADERS,SPApikey" />
    <beans:property name="userDefinedHeaderPrefix" value="" />
</beans:bean>

Body:
Since Spring Integration deals with the Message object in its components and via channels in between, there is a nice solution like supply your important information into the headers and they will be available in the replyMessage for your logging purpose:

<header-enricher>
    <header name="originalPayload" expression="payload"/>
</header-enricher>


问:
tomcat6 and drool rules reloading
I have run into an issue where when I modify my drools rules(.drl) on the fileSystem it appears to work as a JUnit testcase but fails when try to test the same in the web application running under Tomcat6.

When I modify the drl file under Tomcat, I do see logs saying KnowledgeAgent is rebuilding the knowledgeBase and so on and I do see new a instance of KBase under KAgent in the debugger but still when I execute the rule it shows the original values.

Was wondering if there is any cache tomcat uses internally for rules and if yes whats the workaround?
Any help is appreciated.

答:
As I understand your question, I think you have to reload your drl file when it gets changed.

  Are you using ResourceFactory.newClassPathResource() method for loading your rule files?  If yes, then use ResourceFactory.newInputStreamResource(stream) method. It always gets latest  modified drl file.

Title: tomcat6 and drool rules reloading