问:
android UI elements' visibilty not changing
I've been writing an app for FTP file transfer and i need to hide a few UI elements and make a few visible on a button click.The visibility settings remain the same as when the app starts.They do not change.Any idea why?

here are my elements:

ip= (EditText) findViewById(R.id.ipadd);
portt=(EditText) findViewById(R.id.port);
conn= (Button) findViewById(R.id.connectb);
pb= (ProgressBar) findViewById(R.id.pb);
trans=(TextView) findViewById(R.id.transfer);
```

<p>here are the settings at the starting of the app(onCreate):</p>

<pre class="lang-java prettyprint-override"><code>pb.setVisibility(View.INVISIBLE);
trans.setVisibility(View.INVISIBLE);
ip.setVisibility(View.VISIBLE);
portt.setVisibility(View.VISIBLE);
conn.setVisibility(View.VISIBLE);
</code>```

These settings are applied.
And this is the code for the function when the button is clicked:

Ftp ftp;
errflag=false;
ip.setVisibility(View.INVISIBLE);
portt.setVisibility(View.INVISIBLE);
conn.setVisibility(View.INVISIBLE);
trans.setVisibility(View.VISIBLE);
pb.setVisibility(View.VISIBLE);
while(!errflag) {
    try{
      ftp=new Ftp();
      String result = ftp.execute("hi").get();
      if(result.equals("Finished"))
          break;
    } catch(Exception e){
        e.printStackTrace();
    }
}
```

<p>Everything in the code works fine except for the visibility of these elements.
The control enters the while loop and exits properly but doesn't change the visibility of the elements.And yes the function is invoked on button click,so it is in the UI thread,but i've still tried wrapping up the code in runOnUIThread method which doesn't seem to make any changes.
Any comments will be appreciated.</p>

<p>Asynctask code:</p>

```public class Ftp extends AsyncTask<String ,String,String>
{

    protected String doInBackground(String... urls)
    {
        try
        {
            String ipadd= ip.getText().toString();
            int port =Integer.parseInt(portt.getText().toString());
            Socket socket=new Socket(ipadd,port);
            //Button conn=(Button) findViewById(R.id.connectb);

            //conn.setEnabled(false);
            BufferedReader br= new BufferedReader(new InputStreamReader(socket.getInputStream()));
            BufferedOutputStream bo= new BufferedOutputStream(socket.getOutputStream());
            PrintWriter pw= new PrintWriter(bo,true);
            String file=br.readLine();
            if(file.equals("Finished"))
                return file;
            File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES);
            File f= new File(path, "/" + file);
            byte[] buff= new byte[1024];
            int len;
                pw.println("done");
                DataInputStream is= new DataInputStream(socket.getInputStream());
                FileOutputStream fos= new FileOutputStream(f);

            Thread.sleep(1);
            publishProgress(file);
                while((len=is.read(buff))!=-1)
                {

                    fos.write(buff,0,len);

                }
            Log.i("status","Finsihed");

           /* else
            {
                Toast.makeText(MainActivity.this,"File already exists!",Toast.LENGTH_LONG).show();
            }*/
        }catch(NumberFormatException nfe)
        {
            errflag=true;
            runOnUiThread(new Runnable() {
                public void run() {
                    Toast.makeText(MainActivity.this,"Enter a proper IP and port!",Toast.LENGTH_LONG).show();
                }
            });
            nfe.printStackTrace();

        }
        catch(java.net.UnknownHostException un)
        {
            errflag=true;
            runOnUiThread(new Runnable() {
                public void run() {
                    Toast.makeText(MainActivity.this,"Enter a proper IP and port!",Toast.LENGTH_LONG).show();
                }
            });
            //Toast.makeText(MainActivity.this,"Enter a proper IP and port!",Toast.LENGTH_LONG).show();
            un.printStackTrace();
        }
        catch(java.net.NoRouteToHostException no)
        {errflag=true;

            runOnUiThread(new Runnable() {
                public void run() {
                    Toast.makeText(MainActivity.this,"There is no active server at the specified IP and port!",Toast.LENGTH_LONG).show();
                }
            });
            no.printStackTrace();
        }
        catch(Exception e)

        {
            errflag=true;
            Log.i("this","error");
            e.printStackTrace();
        }
        return "Not Yet";
    }
    protected void onProgressUpdate(String... para)
    {
        super.onProgressUpdate(para);
        trans.setText("Transfering file: "+para[0]);

    }

}`
```

<p>Then i made a new thread:</p>

```public class MyThread extends Thread
{
    public void run() {
        while (!errflag) {
            try {
                Ftp ftp = new Ftp();
                String res = ftp.execute("hi").get();
                if (res.equals("Finished"))
                    break;
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
```

<p>and changed the function code to:</p>

```errflag=false;
            ip.setVisibility(View.INVISIBLE);
            portt.setVisibility(View.INVISIBLE);
            conn.setVisibility(View.INVISIBLE);
            trans.setVisibility(View.VISIBLE);
            pb.setVisibility(View.VISIBLE);

        /*ftp=new Ftp();
        String result = ftp.execute("hi").get();
        if(result.equals("Finished"))
            break;*/

        try {
            MyThread t = new MyThread();
            t.start();
        }catch(Exception ex)
        {
            ex.printStackTrace();
        }
```

答:
thanks for your help.I found the solution.Apparently,putting the heavy work on another normal thread wont change anything.AsyncTasks are designed for this purpose.
I read this article : https://tekeye.uk/android/examples/asynctask-helps-avoid-anr
and i put the while loop inside another asynctask class and made UI changes in the "onPreExecute()" and put the loop in the "doInBackground()".It worked like a charm.
This is my code:

```<code>class HeavyWork extends AsyncTask<String,Void,Void>
{
    protected void onPreExecute()
    {
        pb.setVisibility(View.VISIBLE);
        trans.setVisibility(View.VISIBLE);
        ip.setVisibility(View.INVISIBLE);
        portt.setVisibility(View.INVISIBLE);
        conn.setVisibility(View.INVISIBLE);
    }
    protected Void doInBackground(String... urls)
    {
        start();
    return null;
    }
    protected void onPostExecute(Void a)
    {
        pb.setVisibility(View.INVISIBLE);
        trans.setVisibility(View.INVISIBLE);
        ip.setVisibility(View.VISIBLE);
        portt.setVisibility(View.VISIBLE);
        conn.setVisibility(View.VISIBLE);
        trans.setText("Waiting for files");
    }

}
</code>```

The start method is:

```<code> public void start()
{
    while (!errflag) {
        try {
            Ftp ftp = new Ftp();
            String res = ftp.execute("hi").get();
            if (res.equals("Finished"))
                break;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
</code>```

and then i changed the onClick method to:

```<code>errflag=false;

        /*ftp=new Ftp();
        String result = ftp.execute("hi").get();
        if(result.equals("Finished"))
            break;*/

        new HeavyWork().execute("hi");
</code>```

But it seems u can't call an asynctask from another asynctask thread.so u need to call it from a UI thread.In order
to do that,i removed start from doInBackground and pasted it in onPostExecute,as it runs on UI thread,like this:

```<code>class HeavyWork extends AsyncTask<String,Void,Void>
{
    protected void onPreExecute()
    {
        pb.setVisibility(View.VISIBLE);
        trans.setVisibility(View.VISIBLE);
        ip.setVisibility(View.INVISIBLE);
        portt.setVisibility(View.INVISIBLE);
        conn.setVisibility(View.INVISIBLE);
    }
    protected Void doInBackground(String... urls)
    {

    return null;
    }
    protected void onPostExecute(Void a)
    {
        start();
        pb.setVisibility(View.INVISIBLE);
        trans.setVisibility(View.INVISIBLE);
        ip.setVisibility(View.VISIBLE);
        portt.setVisibility(View.VISIBLE);
        conn.setVisibility(View.VISIBLE);
        trans.setText("Waiting for files");
    }

}
</code>```

Small edit:
Apparently,you cannot update progress if u call the second async task on UI thread.SO,i deleted the asynctask and i removed the loop on asynctask,instead, put the loop in asynctask.and i had to remove all the code above the object of ansyctask in the func and paste them in onPreExecute and onPostExecute method.
That's it.It worked.

Thanks a lot guys.Especially Alexander and Nicola.You're wonderful :)

Body:
I've been writing an app for FTP file transfer and i need to hide a few UI elements and make a few visible on a button click.The visibility settings remain the same as when the app starts.They do not change.Any idea why?

here are my elements:

ip= (EditText) findViewById(R.id.ipadd);
portt=(EditText) findViewById(R.id.port);
conn= (Button) findViewById(R.id.connectb);
pb= (ProgressBar) findViewById(R.id.pb);
trans=(TextView) findViewById(R.id.transfer);

here are the settings at the starting of the app(onCreate):

pb.setVisibility(View.INVISIBLE);
trans.setVisibility(View.INVISIBLE);
ip.setVisibility(View.VISIBLE);
portt.setVisibility(View.VISIBLE);
conn.setVisibility(View.VISIBLE);

These settings are applied.
And this is the code for the function when the button is clicked:

Ftp ftp;
errflag=false;
ip.setVisibility(View.INVISIBLE);
portt.setVisibility(View.INVISIBLE);
conn.setVisibility(View.INVISIBLE);
trans.setVisibility(View.VISIBLE);
pb.setVisibility(View.VISIBLE);
while(!errflag) {
    try{
      ftp=new Ftp();
      String result = ftp.execute("hi").get();
      if(result.equals("Finished"))
          break;
    } catch(Exception e){
        e.printStackTrace();
    }
}

Everything in the code works fine except for the visibility of these elements.
The control enters the while loop and exits properly but doesn't change the visibility of the elements.And yes the function is invoked on button click,so it is in the UI thread,but i've still tried wrapping up the code in runOnUIThread method which doesn't seem to make any changes.
Any comments will be appreciated.

Asynctask code:

public class Ftp extends AsyncTask<String ,String,String>
{

    protected String doInBackground(String... urls)
    {
        try
        {
            String ipadd= ip.getText().toString();
            int port =Integer.parseInt(portt.getText().toString());
            Socket socket=new Socket(ipadd,port);
            //Button conn=(Button) findViewById(R.id.connectb);

            //conn.setEnabled(false);
            BufferedReader br= new BufferedReader(new InputStreamReader(socket.getInputStream()));
            BufferedOutputStream bo= new BufferedOutputStream(socket.getOutputStream());
            PrintWriter pw= new PrintWriter(bo,true);
            String file=br.readLine();
            if(file.equals("Finished"))
                return file;
            File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES);
            File f= new File(path, "/" + file);
            byte[] buff= new byte[1024];
            int len;
                pw.println("done");
                DataInputStream is= new DataInputStream(socket.getInputStream());
                FileOutputStream fos= new FileOutputStream(f);

            Thread.sleep(1);
            publishProgress(file);
                while((len=is.read(buff))!=-1)
                {

                    fos.write(buff,0,len);

                }
            Log.i("status","Finsihed");

           /* else
            {
                Toast.makeText(MainActivity.this,"File already exists!",Toast.LENGTH_LONG).show();
            }*/
        }catch(NumberFormatException nfe)
        {
            errflag=true;
            runOnUiThread(new Runnable() {
                public void run() {
                    Toast.makeText(MainActivity.this,"Enter a proper IP and port!",Toast.LENGTH_LONG).show();
                }
            });
            nfe.printStackTrace();

        }
        catch(java.net.UnknownHostException un)
        {
            errflag=true;
            runOnUiThread(new Runnable() {
                public void run() {
                    Toast.makeText(MainActivity.this,"Enter a proper IP and port!",Toast.LENGTH_LONG).show();
                }
            });
            //Toast.makeText(MainActivity.this,"Enter a proper IP and port!",Toast.LENGTH_LONG).show();
            un.printStackTrace();
        }
        catch(java.net.NoRouteToHostException no)
        {errflag=true;

            runOnUiThread(new Runnable() {
                public void run() {
                    Toast.makeText(MainActivity.this,"There is no active server at the specified IP and port!",Toast.LENGTH_LONG).show();
                }
            });
            no.printStackTrace();
        }
        catch(Exception e)

        {
            errflag=true;
            Log.i("this","error");
            e.printStackTrace();
        }
        return "Not Yet";
    }
    protected void onProgressUpdate(String... para)
    {
        super.onProgressUpdate(para);
        trans.setText("Transfering file: "+para[0]);

    }

}`

Then i made a new thread:

public class MyThread extends Thread
{
    public void run() {
        while (!errflag) {
            try {
                Ftp ftp = new Ftp();
                String res = ftp.execute("hi").get();
                if (res.equals("Finished"))
                    break;
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

and changed the function code to:

errflag=false;
            ip.setVisibility(View.INVISIBLE);
            portt.setVisibility(View.INVISIBLE);
            conn.setVisibility(View.INVISIBLE);
            trans.setVisibility(View.VISIBLE);
            pb.setVisibility(View.VISIBLE);

        /*ftp=new Ftp();
        String result = ftp.execute("hi").get();
        if(result.equals("Finished"))
            break;*/

        try {
            MyThread t = new MyThread();
            t.start();
        }catch(Exception ex)
        {
            ex.printStackTrace();
        }

Body:
thanks for your help.I found the solution.Apparently,putting the heavy work on another normal thread wont change anything.AsyncTasks are designed for this purpose.
I read this article : https://tekeye.uk/android/examples/asynctask-helps-avoid-anr
and i put the while loop inside another asynctask class and made UI changes in the "onPreExecute()" and put the loop in the "doInBackground()".It worked like a charm.
This is my code:

class HeavyWork extends AsyncTask<String,Void,Void>
{
    protected void onPreExecute()
    {
        pb.setVisibility(View.VISIBLE);
        trans.setVisibility(View.VISIBLE);
        ip.setVisibility(View.INVISIBLE);
        portt.setVisibility(View.INVISIBLE);
        conn.setVisibility(View.INVISIBLE);
    }
    protected Void doInBackground(String... urls)
    {
        start();
    return null;
    }
    protected void onPostExecute(Void a)
    {
        pb.setVisibility(View.INVISIBLE);
        trans.setVisibility(View.INVISIBLE);
        ip.setVisibility(View.VISIBLE);
        portt.setVisibility(View.VISIBLE);
        conn.setVisibility(View.VISIBLE);
        trans.setText("Waiting for files");
    }

}

The start method is:

 public void start()
{
    while (!errflag) {
        try {
            Ftp ftp = new Ftp();
            String res = ftp.execute("hi").get();
            if (res.equals("Finished"))
                break;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

and then i changed the onClick method to:

errflag=false;

        /*ftp=new Ftp();
        String result = ftp.execute("hi").get();
        if(result.equals("Finished"))
            break;*/

        new HeavyWork().execute("hi");

But it seems u can't call an asynctask from another asynctask thread.so u need to call it from a UI thread.In order
to do that,i removed start from doInBackground and pasted it in onPostExecute,as it runs on UI thread,like this:

class HeavyWork extends AsyncTask<String,Void,Void>
{
    protected void onPreExecute()
    {
        pb.setVisibility(View.VISIBLE);
        trans.setVisibility(View.VISIBLE);
        ip.setVisibility(View.INVISIBLE);
        portt.setVisibility(View.INVISIBLE);
        conn.setVisibility(View.INVISIBLE);
    }
    protected Void doInBackground(String... urls)
    {

    return null;
    }
    protected void onPostExecute(Void a)
    {
        start();
        pb.setVisibility(View.INVISIBLE);
        trans.setVisibility(View.INVISIBLE);
        ip.setVisibility(View.VISIBLE);
        portt.setVisibility(View.VISIBLE);
        conn.setVisibility(View.VISIBLE);
        trans.setText("Waiting for files");
    }

}

Small edit:
Apparently,you cannot update progress if u call the second async task on UI thread.SO,i deleted the asynctask and i removed the loop on asynctask,instead, put the loop in asynctask.and i had to remove all the code above the object of ansyctask in the func and paste them in onPreExecute and onPostExecute method.
That's it.It worked.

Thanks a lot guys.Especially Alexander and Nicola.You're wonderful :)


来源: stackexchange

问:
The method max(Comparator<? super List<Integer>>) in the type Stream<List<Integer>> is not applicable for the arguments (Comparator<Integer>)
I am trying to fetch the student name based on his maximum marks using java8 streams API.

```<code>import static java.util.Arrays.asList;
public class Main {

    public static void main(String args[]) {
        new StudentReport(asList(
                new StudentData("Rohit", asList(100, 81, 82, 83)),
                new StudentData("Ram", asList(84, 85, 86, 87))));
    }
}

import java.util.List;
public class StudentData {

    private String name;
    private List<Integer> marks;

    StudentData(String name, List<Integer> marks) {
        this.name = name;
        this.marks = marks;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public List<Integer> getMarks() {
        return marks;
    }
    public void setMarks(List<Integer> marks) {
        this.marks = marks;
    }
}

import java.util.Comparator;
import java.util.List;
import java.util.stream.Stream;

public class StudentReport {

    public StudentReport(List<StudentData> studentData)
    {
        printStudentNameWithMaxMarks(studentData);
    }

    private void printStudentNameWithMaxMarks(List<StudentData> studentData) {
// I am getting erro here.
        studentData.stream().map(student -> student.getMarks())
        .max(Comparator.comparing(Integer::intValue)).get();
    }

}
</code>```

I would like to return the "Rohit" in output because he scores max 100 marks. whether it is possible to achieve in a single stream operation, compare all the marks and return

```<code>new StudentData("Rohit", asList(100, 81, 82, 83)),
new StudentData("Ram", asList(84, 85, 86, 87))));
</code>```

Thanks in Advance and appreciating your help.

答:
For your current attempt you need to first get the max value for each student before comparing students max values to each other

```<code>studentData.stream().map(student -> Collections.max(student.getMarks()))
        .max(Comparator.comparing(Integer::intValue)).get();
</code>```

The problem with the above code is that it returns the highest mark and not the student so so it needs to be rewritten

```<code>studentData.stream().sorted((s1, s2) -> Collections.max(s1.getMarks()).compareTo(Collections.max(s2.getMarks())))
    .findFirst().get();
</code>```

The code above could be made easier to read if StudentData can give us the highest mark

```<code>public Integer highestMark() {
    return Collections.max(this.getMarks());
}

studentData.stream().sorted((s1, s2) -> s1.highestMark().compareTo(s2.highestMark())).findFirst().get();
</code>```

ContentLicense: CC BY-SA 4.0

Body:
I am trying to fetch the student name based on his maximum marks using java8 streams API.

import static java.util.Arrays.asList;
public class Main {

    public static void main(String args[]) {
        new StudentReport(asList(
                new StudentData("Rohit", asList(100, 81, 82, 83)),
                new StudentData("Ram", asList(84, 85, 86, 87))));
    }
}

import java.util.List;
public class StudentData {

    private String name;
    private List<Integer> marks;

    StudentData(String name, List<Integer> marks) {
        this.name = name;
        this.marks = marks;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public List<Integer> getMarks() {
        return marks;
    }
    public void setMarks(List<Integer> marks) {
        this.marks = marks;
    }
}

import java.util.Comparator;
import java.util.List;
import java.util.stream.Stream;

public class StudentReport {

    public StudentReport(List<StudentData> studentData)
    {
        printStudentNameWithMaxMarks(studentData);
    }

    private void printStudentNameWithMaxMarks(List<StudentData> studentData) {
// I am getting erro here.
        studentData.stream().map(student -> student.getMarks())
        .max(Comparator.comparing(Integer::intValue)).get();
    }

}

I would like to return the "Rohit" in output because he scores max 100 marks. whether it is possible to achieve in a single stream operation, compare all the marks and return

new StudentData("Rohit", asList(100, 81, 82, 83)),
new StudentData("Ram", asList(84, 85, 86, 87))));

Thanks in Advance and appreciating your help.

Body:
For your current attempt you need to first get the max value for each student before comparing students max values to each other

studentData.stream().map(student -> Collections.max(student.getMarks()))
        .max(Comparator.comparing(Integer::intValue)).get();

The problem with the above code is that it returns the highest mark and not the student so so it needs to be rewritten

studentData.stream().sorted((s1, s2) -> Collections.max(s1.getMarks()).compareTo(Collections.max(s2.getMarks())))
    .findFirst().get();

The code above could be made easier to read if StudentData can give us the highest mark

public Integer highestMark() {
    return Collections.max(this.getMarks());
}

studentData.stream().sorted((s1, s2) -> s1.highestMark().compareTo(s2.highestMark())).findFirst().get();


问:
How to retrieve the value of a class from stored procedure
Goal: to use Fluent NHibernate in order retrieve the value of a class into a variable by using a stored procedure.

Problem:

```<code>using (NHibernate.ISession session = FluentNHibernateHelper.OpenSession())
{
    var result = session.CreateSQLQuery("exec test :@data").SetParameter("data", data).AddEntity(typeof(Test));
}
</code>```

It does not work, what code am I missing in order to retrieve the value of class test in the variable result?

In other words, I would like to retrieve the value that is 1, 2 and asdf in a single class and not list.

I'm using C# code.

Thank you!

```<code>CREATE PROCEDURE [dbo].[test]
    @data INT
AS
BEGIN
    SELECT
        1 as a,
        2 as b,
        'asdf' c
END
GO
</code>```

C# class:

```<code>public class Test
{
    public virtual int a { get; set; }
    public virtual int b { get; set; }
    public virtual string c { get; set; }
}

public class TestMap : ClassMap<Test>
{
    public TestMap()
    {
        Id(x => x.a);
        Map(x => x.b);
        Map(x => x.c);
    }
}
</code>```

答:
```<code>.List<T>().Single();
</code>```

You have to retrieve all the data and then retrieve a single data.

Not the recommended solution but it solved the case.

Body:
Goal: to use Fluent NHibernate in order retrieve the value of a class into a variable by using a stored procedure.

Problem:

using (NHibernate.ISession session = FluentNHibernateHelper.OpenSession())
{
    var result = session.CreateSQLQuery("exec test :@data").SetParameter("data", data).AddEntity(typeof(Test));
}

It does not work, what code am I missing in order to retrieve the value of class test in the variable result?

In other words, I would like to retrieve the value that is 1, 2 and asdf in a single class and not list.

I'm using C# code.

Thank you!

CREATE PROCEDURE [dbo].[test]
    @data INT
AS
BEGIN
    SELECT
        1 as a,
        2 as b,
        'asdf' c
END
GO

C# class:

public class Test
{
    public virtual int a { get; set; }
    public virtual int b { get; set; }
    public virtual string c { get; set; }
}

public class TestMap : ClassMap<Test>
{
    public TestMap()
    {
        Id(x => x.a);
        Map(x => x.b);
        Map(x => x.c);
    }
}

Body:
.List<T>().Single();

You have to retrieve all the data and then retrieve a single data.

Not the recommended solution but it solved the case.


问:
Replace NA values depending on specific rules
I am working on a dataset where a score calculated based on data collected from a clinical record. In some cases this data has been  omitted and so the score cannot be calculated and is recorded as NA.

In some cases I am able to substitute an NA value with a previous value. The limitations for this approach are:

If score is NA check whether previous and next values are NA. If both previous and next values are not NA then insert the mean of those scores.

If score is NA check whether previous and next values are NA. IF only previous value is not NA then replace first NA value with previous value.

If there are two or more NA values in sequence only replace the fist NA value leave others as NA.

I have tried the function zoo::na.locf() but this indiscriminately either will replace all NA's or limit to replacing Gaps greated than a number of NAs.

I looked at tidy fill but the documentation didn't include anything about setting limits for filling.

For the following data:

```<code>ID,episode,score
1,1,1
1,2,1
1,3,1
1,4,NA
1,5,NA
1,6,NA
1,7,2
1,8,NA
1,9,4
1,10,NA
2,1,NA
2,2,2
2,3,3
2,4,4
2,5,NA
2,6,NA
2,7,3
2,8,NA
2,9,NA
2,10,NA
</code>```

So I think that I am on the right track with the below nested ifelse mutate but I'm missing knowledge about functions that I can use to limit my replacement to certain numbers of NA values

data <- data %>%
group_by(ID) %>%
arrange(episode) %>%
mutate(score = ifelse(is.na(score) & lag(!is.na(score)) & lead(!is.na(score)), average(sum(lag(score),lead(score))),
    ifelse(is.na(score) & lag(!is.na(score)) & lead(is.na(score)), lag(score), ...) #And this is where I get stuck as I am unsure how to code for NA runs greater than 1
```

<p>My expected output would be:</p>

```ID,episode,score
1,1,1
1,2,1
1,3,1
1,4,*1
1,5,NA
1,6,NA
1,7,2
1,8,*3
1,9,4
1,10,*4
2,1,NA
2,2,2
2,3,3
2,4,4
2,5,*4
2,6,NA
2,7,3
2,8,*3
2,9,NA
2,10,NA

```

*s added to make it clear where values are copied.

答:
An option would be</p>

```<code>library(dplyr)
data %>%
   group_by(ID) %>%
  group_by(grp = cumsum(lead(is.na(score) & !is.na(lead(score) &
      !is.na(lag(score)) ))), add = TRUE) %>%
  mutate(score1 = if(n() == 3 & is.na(score[2]) & sum(is.na(score))== 1)
    replace(score, is.na(score), mean(score, na.rm = TRUE)) else score) %>%
  ungroup %>%
  select(-grp) %>%
  mutate(score1 = coalesce(score1, lag(score1)))
# A tibble: 20 x 4
#      ID episode score score1
#   <int>   <int> <int>  <dbl>
# 1     1       1     1      1
# 2     1       2     1      1
# 3     1       3     1      1
# 4     1       4    NA      1
# 5     1       5    NA     NA
# 6     1       6    NA     NA
# 7     1       7     2      2
# 8     1       8    NA      3
# 9     1       9     4      4
#10     1      10    NA      4
#11     2       1    NA     NA
#12     2       2     2      2
#13     2       3     3      3
#14     2       4     4      4
#15     2       5    NA      4
#16     2       6    NA     NA
#17     2       7     3      3
#18     2       8    NA      3
#19     2       9    NA     NA
#20     2      10    NA     NA
</code>```

Body:
I am working on a dataset where a score calculated based on data collected from a clinical record. In some cases this data has been  omitted and so the score cannot be calculated and is recorded as NA.

In some cases I am able to substitute an NA value with a previous value. The limitations for this approach are:

If score is NA check whether previous and next values are NA. If both previous and next values are not NA then insert the mean of those scores.

If score is NA check whether previous and next values are NA. IF only previous value is not NA then replace first NA value with previous value.

If there are two or more NA values in sequence only replace the fist NA value leave others as NA.

I have tried the function zoo::na.locf() but this indiscriminately either will replace all NA's or limit to replacing Gaps greated than a number of NAs.

I looked at tidy fill but the documentation didn't include anything about setting limits for filling.

For the following data:

ID,episode,score
1,1,1
1,2,1
1,3,1
1,4,NA
1,5,NA
1,6,NA
1,7,2
1,8,NA
1,9,4
1,10,NA
2,1,NA
2,2,2
2,3,3
2,4,4
2,5,NA
2,6,NA
2,7,3
2,8,NA
2,9,NA
2,10,NA

So I think that I am on the right track with the below nested ifelse mutate but I'm missing knowledge about functions that I can use to limit my replacement to certain numbers of NA values

data <- data %>%
group_by(ID) %>%
arrange(episode) %>%
mutate(score = ifelse(is.na(score) & lag(!is.na(score)) & lead(!is.na(score)), average(sum(lag(score),lead(score))),
    ifelse(is.na(score) & lag(!is.na(score)) & lead(is.na(score)), lag(score), ...) #And this is where I get stuck as I am unsure how to code for NA runs greater than 1

My expected output would be:

ID,episode,score
1,1,1
1,2,1
1,3,1
1,4,*1
1,5,NA
1,6,NA
1,7,2
1,8,*3
1,9,4
1,10,*4
2,1,NA
2,2,2
2,3,3
2,4,4
2,5,*4
2,6,NA
2,7,3
2,8,*3
2,9,NA
2,10,NA

*s added to make it clear where values are copied.

Body:
An option would be

library(dplyr)
data %>%
   group_by(ID) %>%
  group_by(grp = cumsum(lead(is.na(score) & !is.na(lead(score) &
      !is.na(lag(score)) ))), add = TRUE) %>%
  mutate(score1 = if(n() == 3 & is.na(score[2]) & sum(is.na(score))== 1)
    replace(score, is.na(score), mean(score, na.rm = TRUE)) else score) %>%
  ungroup %>%
  select(-grp) %>%
  mutate(score1 = coalesce(score1, lag(score1)))
# A tibble: 20 x 4
#      ID episode score score1
#   <int>   <int> <int>  <dbl>
# 1     1       1     1      1
# 2     1       2     1      1
# 3     1       3     1      1
# 4     1       4    NA      1
# 5     1       5    NA     NA
# 6     1       6    NA     NA
# 7     1       7     2      2
# 8     1       8    NA      3
# 9     1       9     4      4
#10     1      10    NA      4
#11     2       1    NA     NA
#12     2       2     2      2
#13     2       3     3      3
#14     2       4     4      4
#15     2       5    NA      4
#16     2       6    NA     NA
#17     2       7     3      3
#18     2       8    NA      3
#19     2       9    NA     NA
#20     2      10    NA     NA


问:
Build issue in electron application
I have build a simple app using electron and its works fine when you launch with npm start. After i am try to deploy my application, I am getting following error.

WARNING: --asar does not take any arguments, it only has
  sub-properties (see --help) Packaging app for platform win32 ia32
  using electron v4.1.3 WARNING: Found 'electron' but not as a
  devDependency, pruning anyway rcedit.exe failed with exit code 1.
  Reserved header is not 0 or image type is not icon for 'a' Fatal
  error: Unable to set icon npm ERR! code ELIFECYCLE npm ERR! errno 1
  npm ERR! shoppinglist@1.0.0 package-win: electron-packager .
  electron-tutorial-app --overwrite --asar=true --platform=win32
  --arch=ia32 --icon=assets/icons/win/icon.ico --prune=true --out=release-builds --version-string.CompanyName=CE --version-string.FileDescription=CE --version-string.ProductName="ShoppingList" npm ERR! Exit status 1 npm ERR! npm ERR! Failed at the shoppinglist@1.0.0 package-win script.
  npm ERR! This is probably not a problem with npm. There is likely
  additional logging output above.`

I already tried npm cache clean --force and install node modules again by npm install did't worked in my case. can anyone help me with this please?

package.json

```<code>{
  "name": "shoppinglist",
  "version": "1.0.0",
  "description": "Electron shoppinglist desktop app",
  "main": "main.js",
  "scripts": {
    "start": "electron .",
    "package-mac": "electron-packager . --overwrite --platform=darwin --arch=x64 --icon=assets/icons/mac/icon.icns --prune=true --out=release-builds",
    "package-win": "electron-packager . --overwrite --asar=true --platform=win32 --arch=ia32 --icon=assets/icons/win/icon.ico --prune=true --out=release-builds --version-string.CompanyName=CE --version-string.FileDescription=CE --version-string.ProductName=\"Shopping List\"",
    "package-linux" : "electron-packager . --overwrite --platform=linux --arch=x64 --icon=assets/icons/png/icon.png --prune=true --out=release-builds"
  },
  "license": "ISC",
  "dependencies": {
    "electron": "^1.7.6"
  },
  "devDependencies": {
    "electron-packager": "^9.0.1"
  }
}
</code>```

答:
This can be happen for some reason your cache gets corrupted with some conflicting versions of different dependencies but in your case, you have already run npm cache clean and reinstalled all the node modules.

Please check folder paths that you have given to the package.json. This might fix your problem.

Title: Build issue in electron application

Body:
I have build a simple app using electron and its works fine when you launch with npm start. After i am try to deploy my application, I am getting following error.

WARNING: --asar does not take any arguments, it only has
  sub-properties (see --help) Packaging app for platform win32 ia32
  using electron v4.1.3 WARNING: Found 'electron' but not as a
  devDependency, pruning anyway rcedit.exe failed with exit code 1.
  Reserved header is not 0 or image type is not icon for 'a' Fatal
  error: Unable to set icon npm ERR! code ELIFECYCLE npm ERR! errno 1
  npm ERR! shoppinglist@1.0.0 package-win: electron-packager .
  electron-tutorial-app --overwrite --asar=true --platform=win32
  --arch=ia32 --icon=assets/icons/win/icon.ico --prune=true --out=release-builds --version-string.CompanyName=CE --version-string.FileDescription=CE --version-string.ProductName="ShoppingList" npm ERR! Exit status 1 npm ERR! npm ERR! Failed at the shoppinglist@1.0.0 package-win script.
  npm ERR! This is probably not a problem with npm. There is likely
  additional logging output above.`

I already tried npm cache clean --force and install node modules again by npm install did't worked in my case. can anyone help me with this please?

package.json

{
  "name": "shoppinglist",
  "version": "1.0.0",
  "description": "Electron shoppinglist desktop app",
  "main": "main.js",
  "scripts": {
    "start": "electron .",
    "package-mac": "electron-packager . --overwrite --platform=darwin --arch=x64 --icon=assets/icons/mac/icon.icns --prune=true --out=release-builds",
    "package-win": "electron-packager . --overwrite --asar=true --platform=win32 --arch=ia32 --icon=assets/icons/win/icon.ico --prune=true --out=release-builds --version-string.CompanyName=CE --version-string.FileDescription=CE --version-string.ProductName=\"Shopping List\"",
    "package-linux" : "electron-packager . --overwrite --platform=linux --arch=x64 --icon=assets/icons/png/icon.png --prune=true --out=release-builds"
  },
  "license": "ISC",
  "dependencies": {
    "electron": "^1.7.6"
  },
  "devDependencies": {
    "electron-packager": "^9.0.1"
  }
}


问:
Syntax Error :can't assign to function call
This is my code below

```<code>plt.figure(1), plt.subplot(121), df=train.dropna(),
sns.distplot(df['LoanAmount'])
</code>```

I am getting an error like this

```<code>> SyntaxError: can't assign to function call
</code>```

答:
There are a few things wrong with the code, but I will point out the major points:

```<code>plt.figure(1), plt.subplot(121), df=train.dropna(), sns.distplot(df['LoanAmount'])
</code>```

The commas are interpreted as the line being a tuple, with the equals indicating left and right hand sides, in the same way that

```<code>x, y, z = 1, 2, 3
</code>```

Would be, i.e.:

```<code>plt.figure(1), plt.subplot(121), df =
    train.dropna(), sns.distplot(df['LoanAmount'])
</code>```

.  What you probably meant was

```<code>plt.figure(1)
plt.subplot(121)
df = train.dropna()
sns.distplot(df['LoanAmount'])
</code>```

which you could write (not advisable) as

```<code>plt.figure(1); plt.subplot(121); df=train.dropna(); sns.distplot(df['LoanAmount'])
</code>```

The main error you see is correct, you can't have a line like

```<code>a() = b
</code>```

That assigns to a function call (it would have no meaning), which you do in the original interpretation.

Body:
This is my code below

plt.figure(1), plt.subplot(121), df=train.dropna(),
sns.distplot(df['LoanAmount'])

I am getting an error like this

> SyntaxError: can't assign to function call

Body:
There are a few things wrong with the code, but I will point out the major points:

plt.figure(1), plt.subplot(121), df=train.dropna(), sns.distplot(df['LoanAmount'])

The commas are interpreted as the line being a tuple, with the equals indicating left and right hand sides, in the same way that

x, y, z = 1, 2, 3

Would be, i.e.:

plt.figure(1), plt.subplot(121), df =
    train.dropna(), sns.distplot(df['LoanAmount'])

.  What you probably meant was

plt.figure(1)
plt.subplot(121)
df = train.dropna()
sns.distplot(df['LoanAmount'])

which you could write (not advisable) as

plt.figure(1); plt.subplot(121); df=train.dropna(); sns.distplot(df['LoanAmount'])

The main error you see is correct, you can't have a line like

a() = b

That assigns to a function call (it would have no meaning), which you do in the original interpretation.


问:
SQL server updating records where they exist
```<code>update [db2].dbo.tblASDF
set deviceID = (select db1.deviceID FROM [database1].[dbo].[device] as db1,[database2].[dbo].[device] as db2 where db1.name = db2.name)
where exists (select * FROM [database1].[dbo].[device] as db1,[database2].[dbo].[device] as db2 where db1.name = db2.name)
</code>```

Question/Statement1: It's not important that I'm selecting * in the "where exists", what's important is that my "where db1.name = db2.name" clause is returning the rows which meet this condition, because these rows hold the unique keys to help my update to operate? IE, whether I've selected one or 20 columns is irrelevant.

Question2: I'm pulling from 2 databases, db1 and db2. Does the "exists" know to use the unique keys from db1/db2 to update db2's tblASDF.deviceID column? ie, it doesn't matter that there are 2 sets of unique keys (the ones for the db1, and the ones for the db2) returned from the "where db1.name = db2.name"?

答:
exists returns only true or false, it doesn't have anything to do with keys. Imagine it like it returns true whenever more than one row is returned from the subquery and false when 0 rows returned.

You could replace exists (select * FROM... with exists (select 1 FROM... so that you don't select any column (you can't use the data anyways).

I hope this answers your questions. Please correct me if I'm wrong :)

ContentLicense: CC BY-SA 3.0

Body:
update [db2].dbo.tblASDF
set deviceID = (select db1.deviceID FROM [database1].[dbo].[device] as db1,[database2].[dbo].[device] as db2 where db1.name = db2.name)
where exists (select * FROM [database1].[dbo].[device] as db1,[database2].[dbo].[device] as db2 where db1.name = db2.name)

Question/Statement1: It's not important that I'm selecting * in the "where exists", what's important is that my "where db1.name = db2.name" clause is returning the rows which meet this condition, because these rows hold the unique keys to help my update to operate? IE, whether I've selected one or 20 columns is irrelevant.

Question2: I'm pulling from 2 databases, db1 and db2. Does the "exists" know to use the unique keys from db1/db2 to update db2's tblASDF.deviceID column? ie, it doesn't matter that there are 2 sets of unique keys (the ones for the db1, and the ones for the db2) returned from the "where db1.name = db2.name"?


问:
Function to insert text line by line from a file into string array passed by pointer
I'm trying to create a function read_lines that takes a file *fp, a pointer to char** lines, and pointer to int num_lines. The function should insert each line of text into lines, and increase num_lines to however many lines the file has.

Its probably really simple but I've been trying to insert the text for several hours now.

This is what main.c would look like. Everything but read_lines is already defined and working.

```<code>int main(int argc, char* argv[]){

    char** lines = NULL;
    int num_lines = 0;
    FILE* fp = validate_input(argc, argv);
    read_lines(fp, &lines, &num_lines);
    print_lines(lines, num_lines);
    free_lines(lines, num_lines);
    fclose(fp);

    return 0;
}
</code>```

This is one of my attempts at trying to append lines, but I couldn't figure it out.

read_lines.c

```<code>void read_lines(FILE *fp, char ***lines, int *num_lines) {
    int i;
    int N = 0;
    char s[200];
    for (i=0; i<3; i++)
    {
        while(fgets(s, 200, fp)!=NULL){N++;}
        char strings[50][200];

        rewind(fp);
        fgets(s, 200, fp);
        strcpy(lines[i],s);
    }

}
</code>```

I'd appreciate any help at solving this, thanks.

答:
```<code>assuming you have allocated enough memory to lines, following should work
if not you have to malloc/calloc() for lines[i] before doing strcpy() in every
iteration of the loop.

void read_lines(FILE *fp, char ***lines, int *num_lines) {
       int N = 0;
       char s[200];
       while(fgets(s, 200, fp)!=NULL){
             N++;
             strcpy((*lines)[N],s);
       }
       *num_lines = N; // update pointer with value of N which is number of lines in file
}
</code>```

Body:
I'm trying to create a function read_lines that takes a file *fp, a pointer to char** lines, and pointer to int num_lines. The function should insert each line of text into lines, and increase num_lines to however many lines the file has.

Its probably really simple but I've been trying to insert the text for several hours now.

This is what main.c would look like. Everything but read_lines is already defined and working.

int main(int argc, char* argv[]){

    char** lines = NULL;
    int num_lines = 0;
    FILE* fp = validate_input(argc, argv);
    read_lines(fp, &lines, &num_lines);
    print_lines(lines, num_lines);
    free_lines(lines, num_lines);
    fclose(fp);

    return 0;
}

This is one of my attempts at trying to append lines, but I couldn't figure it out.

read_lines.c

void read_lines(FILE *fp, char ***lines, int *num_lines) {
    int i;
    int N = 0;
    char s[200];
    for (i=0; i<3; i++)
    {
        while(fgets(s, 200, fp)!=NULL){N++;}
        char strings[50][200];

        rewind(fp);
        fgets(s, 200, fp);
        strcpy(lines[i],s);
    }

}

I'd appreciate any help at solving this, thanks.


问:
Making array populations in functions instantaneous
I set an array
let A1 = []

then create a function to populate the array

```<code>function popA1() {
  let x = new Array(v1, v2, v3, vn);
  return A1 = x;
}

function basicTableGenerator(myArray) {
    let result = "<table><thead><th>Table</th></thead>";
    for(let i=0; i<myArray.length; i++) {
        result += "<tr><td>" + myArray[i] + "</td></tr>";
    }
    result += </table>";
    return result;
}
</code>```

and that function is called by a button click

```<code>button.addEventListener("click", () => {
  if (A1.length == 0) {
    popA1();
  }
  generateTableFromA1(A1);
}
</code>```

It works well and all, except for the tiny fact that generateTableFromA1() won't work until the second time I click that button, how do I get it to work the first time?

答:
```<code>function popA1() {
  let x = new Array(v1, v2, v3, vn);
  A1 = x;
}
</code>```

try to remove return

Body:
I set an array
let A1 = []

then create a function to populate the array

function popA1() {
  let x = new Array(v1, v2, v3, vn);
  return A1 = x;
}

function basicTableGenerator(myArray) {
    let result = "

Table
";
    for(let i=0; i<myArray.length; i++) {
        result += "
" + myArray[i] + "
";
    }
    result +=
";
    return result;
}

and that function is called by a button click

button.addEventListener("click", () => {
  if (A1.length == 0) {
    popA1();
  }
  generateTableFromA1(A1);
}

It works well and all, except for the tiny fact that generateTableFromA1() won't work until the second time I click that button, how do I get it to work the first time?

Body:
function popA1() {
  let x = new Array(v1, v2, v3, vn);
  A1 = x;
}

try to remove return


问:
Swift : Sort array by natural order
I'm having an dictionary with order here:

```<code>var pickerData = [
    "en":"abc",
    "jp":"xyz",
    "fr":"gya",
    "zh-CN":"uio"]
</code>```

But when i println() pickerData.keys.array , the order is not like thit.
I want to sort pickerData.keys.array by order above.
Is it posible?

答:
Since Swift 4 and 5 this has got a lot easier:</p>

```<code>for mySortedKey in pickerData.keys.sorted() {
    [....]
}
</code>```

Title: Swift : Sort array by natural order

Body:
I'm having an dictionary with order here:

var pickerData = [
    "en":"abc",
    "jp":"xyz",
    "fr":"gya",
    "zh-CN":"uio"]

But when i println() pickerData.keys.array , the order is not like thit.
I want to sort pickerData.keys.array by order above.
Is it posible?

Body:
Since Swift 4 and 5 this has got a lot easier:

for mySortedKey in pickerData.keys.sorted() {
    [....]
}


问:
Laravel: Session message exist while click on browser back button
In Laravel 5.5, I am having crud operation for slider, the store method is as follows

```<code>public function store(StoreSlider $request)
{
    $image = $request->image;
    $name = $request->name;
    $status = $request->status;

    $path = Storage::putFile('slider', $image);
    Slider::create([ 'name' => $name, 'image' => $path, 'status' => $status ]);
    Session::flash('message', 'Slider added successfullly');
    return redirect()->route('slider.index');
}
</code>```

It redirects to index page, and shows the message Slider added successfullly and i am using the below code to display the session:

```<code>@if(Session::has('message'))
    <p class="alert_msg"><i class="icon-correct-signal"></i> {{ Session::get('message') }}</p>
@endif
</code>```

and i am hiding the above message with the following code,

```<code>setTimeout(function() {
    $('.alert_msg').fadeOut('fast');
}, 3000);
</code>```

All the above are working fine.

In index page the message once shows and hides.

In index page having view option, that show the added slider, if i come back by click any URL, the session message not showing. Perfect

The problem is while in view page i come back by click on browser back button the session message shows again

Can't able to find whats the issue.

答:
use the following headers</p>

```<code>header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
</code>```

Body:
In Laravel 5.5, I am having crud operation for slider, the store method is as follows

public function store(StoreSlider $request)
{
    $image = $request->image;
    $name = $request->name;
    $status = $request->status;

    $path = Storage::putFile('slider', $image);
    Slider::create([ 'name' => $name, 'image' => $path, 'status' => $status ]);
    Session::flash('message', 'Slider added successfullly');
    return redirect()->route('slider.index');
}

It redirects to index page, and shows the message Slider added successfullly and i am using the below code to display the session:

@if(Session::has('message'))

 {{ Session::get('message') }}

@endif

and i am hiding the above message with the following code,

setTimeout(function() {
    $('.alert_msg').fadeOut('fast');
}, 3000);

All the above are working fine.

In index page the message once shows and hides.

In index page having view option, that show the added slider, if i come back by click any URL, the session message not showing. Perfect

The problem is while in view page i come back by click on browser back button the session message shows again

Can't able to find whats the issue.

Body:
use the following headers

header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");


问:
What is better to use just one method with switch or 4 different methods?
I have a object and i get some fields from it, i made a method with a switch statement, the idea was make it generic and just call this method through parameters but now I´m not sure.

The options are

```<code>private String getCode(Row row, String code) {
    String result;
    switch (code) {
      case code1:
        result = row.getString("constant1");
        break;
      case code2:
        result = row.getString(constant2);
        break;
      case code3:
        result = row.getString(constant3);
        break;
      case code4:
        result = row.getString(constant4);
        break;
      default:
        result = null;
    }
    return result;
  }
</code>```

or

```<code>private String getcode1(Row row){
    return row.getString("constant1")
  }

  private String getcode1(Row row){
    return row.getString("constant2")
  }
  private String getcode1(Row row){
    return row.getString("constant3")
  }

  private String getcode1(Row row){
    return row.getString("constant4")
  }
</code>```

I wand to use the better way, I´m a little confuse

答:
Create an enum for mapping of code and constant. In that enum, create a generic method where you can get code just passing through parameter.

```<code>public enum MyEnum {

    CODE1("constant1"), CODE2("constant2");

    private String constant;

    public String getConstant() {
        return constant;
    }

    private MyEnum(String constant) {
        this.constant = constant;
    }

    private static String getConstant(String code) {
        return Arrays.stream(MyEnum.values()).filter(mapping -> mapping.name().equalsIgnoreCase(code))
                .map(e -> e.getConstant()).findAny().orElse(null);
    }

    public static String getCode(Row row, String code) {
        String constant = getConstant(code);
        return constant != null ? row.get(constant) : null;

    }

}
</code>```

You can get code from row object by calling genric method getCode().

```<code>MyEnum.getCode(row, "code1")
</code>```

Body:
I have a object and i get some fields from it, i made a method with a switch statement, the idea was make it generic and just call this method through parameters but now I´m not sure.

The options are

private String getCode(Row row, String code) {
    String result;
    switch (code) {
      case code1:
        result = row.getString("constant1");
        break;
      case code2:
        result = row.getString(constant2);
        break;
      case code3:
        result = row.getString(constant3);
        break;
      case code4:
        result = row.getString(constant4);
        break;
      default:
        result = null;
    }
    return result;
  }

or

private String getcode1(Row row){
    return row.getString("constant1")
  }

  private String getcode1(Row row){
    return row.getString("constant2")
  }
  private String getcode1(Row row){
    return row.getString("constant3")
  }

  private String getcode1(Row row){
    return row.getString("constant4")
  }

I wand to use the better way, I´m a little confuse

Body:
Create an enum for mapping of code and constant. In that enum, create a generic method where you can get code just passing through parameter.

public enum MyEnum {

    CODE1("constant1"), CODE2("constant2");

    private String constant;

    public String getConstant() {
        return constant;
    }

    private MyEnum(String constant) {
        this.constant = constant;
    }

    private static String getConstant(String code) {
        return Arrays.stream(MyEnum.values()).filter(mapping -> mapping.name().equalsIgnoreCase(code))
                .map(e -> e.getConstant()).findAny().orElse(null);
    }

    public static String getCode(Row row, String code) {
        String constant = getConstant(code);
        return constant != null ? row.get(constant) : null;

    }

}

You can get code from row object by calling genric method getCode().

MyEnum.getCode(row, "code1")


问:
To print the boundary of Binary Tree
I have been asked in an interviews to print the boundary of the Binary Tree. For example.

```<code>      1
   /    \
  2      3
 /  \   /  \
4    5 6    7
    /   \     \
   8     9     10
</code>```

Answer will be : 1, 2, 4, 8, 9, 10, 7, 3

I have given the following answer.

First Method :

I have used a  Bool  variable to solve the above problem.

```<code>void printLeftEdges(BinaryTree *p, bool print) {
   if (!p) return;
   if (print || (!p->left && !p->right))
       cout << p->data << " ";
   printLeftEdges(p->left, print);
   printLeftEdges(p->right, false);
}

void printRightEdges(BinaryTree *p, bool print) {
   if (!p) return;
   printRightEdges(p->left, false);
   printRightEdges(p->right, print);
   if (print || (!p->left && !p->right))
   cout << p->data << " ";
}

void printOuterEdges(BinaryTree *root) {
   if (!root) return;
   cout << root->data << " ";
   printLeftEdges(root->left, true);
   printRightEdges(root->right, true);
}
</code>```

His Response : You have used  Bool  variable so many times. Can you solve this without using that.

Second Method :

I simply used tree traversal to solve this problem.

```<code>1. Print the left boundary in top-down manner.
2. Print all leaf nodes from left to right, which can again be sub-divided into two sub-parts:
     2.1 Print all leaf nodes of left sub-tree from left to right.
     2.2 Print all leaf nodes of right subtree from left to right.
3. Print the right boundary in bottom-up manner.
</code>```

His Response : He was not happy with this method too. He told that you are traversing the tree 3 times. That is too much. Give another solution if you have any.

Third Method :
This time i have went for Level Order traversal (BFS).

```<code> 1: Print starting and ending node of each level
 2: For each other node check if its both the children are <b>NULL</b> then print that node too.
</code>```

His Response : He was not seems happy with this method too because this method takes extra memory of order O(n).

My question is that Tell me a method which traverse tree single times, do not use any Bool variable and do not use any extra memory. Is it possible?

答:
Hope this helps:

```<code>// Java program to print boundary traversal of binary tree

/* A binary tree node has data, pointer to left child
   and a pointer to right child */
class Node {
int data;
Node left, right;

 Node(int item)
 {
    data = item;
    left = right = null;
 }
}

class BinaryTree {
Node root;

// A simple function to print leaf nodes of a binary tree
void printLeaves(Node node)
{
    if (node != null) {
        printLeaves(node.left);

        // Print it if it is a leaf node
        if (node.left == null && node.right == null)
            System.out.print(node.data + " ");
        printLeaves(node.right);
    }
}

// A function to print all left boundary nodes, except a leaf node.
// Print the nodes in TOP DOWN manner
void printBoundaryLeft(Node node)
{
    if (node != null) {
        if (node.left != null) {

            // to ensure top down order, print the node
            // before calling itself for left subtree
            System.out.print(node.data + " ");
            printBoundaryLeft(node.left);
        }
        else if (node.right != null) {
            System.out.print(node.data + " ");
            printBoundaryLeft(node.right);
        }

        // do nothing if it is a leaf node, this way we avoid
        // duplicates in output
    }
}

// A function to print all right boundary nodes, except a leaf node
// Print the nodes in BOTTOM UP manner
void printBoundaryRight(Node node)
{
    if (node != null) {
        if (node.right != null) {
            // to ensure bottom up order, first call for right
            // subtree, then print this node
            printBoundaryRight(node.right);
            System.out.print(node.data + " ");
        }
        else if (node.left != null) {
            printBoundaryRight(node.left);
            System.out.print(node.data + " ");
        }
        // do nothing if it is a leaf node, this way we avoid
        // duplicates in output
    }
}

// A function to do boundary traversal of a given binary tree
void printBoundary(Node node)
{
    if (node != null) {
        System.out.print(node.data + " ");

        // Print the left boundary in top-down manner.
        printBoundaryLeft(node.left);

        // Print all leaf nodes
        printLeaves(node.left);
        printLeaves(node.right);

        // Print the right boundary in bottom-up manner
        printBoundaryRight(node.right);
    }
}

// Driver program to test above functions
public static void main(String args[])
{
    BinaryTree tree = new BinaryTree();
    tree.root = new Node(20);
    tree.root.left = new Node(8);
    tree.root.left.left = new Node(4);
    tree.root.left.right = new Node(12);
    tree.root.left.right.left = new Node(10);
    tree.root.left.right.right = new Node(14);
    tree.root.right = new Node(22);
    tree.root.right.right = new Node(25);
    tree.printBoundary(tree.root);
}
}
</code>```

Boundary Traversal of binary tree

Title: To print the boundary of Binary Tree

Body:
I have been asked in an interviews to print the boundary of the Binary Tree. For example.

      1
   /    \
  2      3
 /  \   /  \
4    5 6    7
    /   \     \
   8     9     10

Answer will be : 1, 2, 4, 8, 9, 10, 7, 3

I have given the following answer.

First Method :

I have used a  Bool  variable to solve the above problem.

void printLeftEdges(BinaryTree *p, bool print) {
   if (!p) return;
   if (print || (!p->left && !p->right))
       cout <
data << " ";
   printLeftEdges(p->left, print);
   printLeftEdges(p->right, false);
}

void printRightEdges(BinaryTree *p, bool print) {
   if (!p) return;
   printRightEdges(p->left, false);
   printRightEdges(p->right, print);
   if (print || (!p->left && !p->right))
   cout <
data << " ";
}

void printOuterEdges(BinaryTree *root) {
   if (!root) return;
   cout << root->data << " ";
   printLeftEdges(root->left, true);
   printRightEdges(root->right, true);
}

His Response : You have used  Bool  variable so many times. Can you solve this without using that.

Second Method :

I simply used tree traversal to solve this problem.

1. Print the left boundary in top-down manner.
2. Print all leaf nodes from left to right, which can again be sub-divided into two sub-parts:
     2.1 Print all leaf nodes of left sub-tree from left to right.
     2.2 Print all leaf nodes of right subtree from left to right.
3. Print the right boundary in bottom-up manner.

His Response : He was not happy with this method too. He told that you are traversing the tree 3 times. That is too much. Give another solution if you have any.

Third Method :
This time i have went for Level Order traversal (BFS).

 1: Print starting and ending node of each level
 2: For each other node check if its both the children are NULL then print that node too.

His Response : He was not seems happy with this method too because this method takes extra memory of order O(n).

My question is that Tell me a method which traverse tree single times, do not use any Bool variable and do not use any extra memory. Is it possible?

Body:
Hope this helps:

// Java program to print boundary traversal of binary tree

/* A binary tree node has data, pointer to left child
   and a pointer to right child */
class Node {
int data;
Node left, right;

 Node(int item)
 {
    data = item;
    left = right = null;
 }
}

class BinaryTree {
Node root;

// A simple function to print leaf nodes of a binary tree
void printLeaves(Node node)
{
    if (node != null) {
        printLeaves(node.left);

        // Print it if it is a leaf node
        if (node.left == null && node.right == null)
            System.out.print(node.data + " ");
        printLeaves(node.right);
    }
}

// A function to print all left boundary nodes, except a leaf node.
// Print the nodes in TOP DOWN manner
void printBoundaryLeft(Node node)
{
    if (node != null) {
        if (node.left != null) {

            // to ensure top down order, print the node
            // before calling itself for left subtree
            System.out.print(node.data + " ");
            printBoundaryLeft(node.left);
        }
        else if (node.right != null) {
            System.out.print(node.data + " ");
            printBoundaryLeft(node.right);
        }

        // do nothing if it is a leaf node, this way we avoid
        // duplicates in output
    }
}

// A function to print all right boundary nodes, except a leaf node
// Print the nodes in BOTTOM UP manner
void printBoundaryRight(Node node)
{
    if (node != null) {
        if (node.right != null) {
            // to ensure bottom up order, first call for right
            // subtree, then print this node
            printBoundaryRight(node.right);
            System.out.print(node.data + " ");
        }
        else if (node.left != null) {
            printBoundaryRight(node.left);
            System.out.print(node.data + " ");
        }
        // do nothing if it is a leaf node, this way we avoid
        // duplicates in output
    }
}

// A function to do boundary traversal of a given binary tree
void printBoundary(Node node)
{
    if (node != null) {
        System.out.print(node.data + " ");

        // Print the left boundary in top-down manner.
        printBoundaryLeft(node.left);

        // Print all leaf nodes
        printLeaves(node.left);
        printLeaves(node.right);

        // Print the right boundary in bottom-up manner
        printBoundaryRight(node.right);
    }
}

// Driver program to test above functions
public static void main(String args[])
{
    BinaryTree tree = new BinaryTree();
    tree.root = new Node(20);
    tree.root.left = new Node(8);
    tree.root.left.left = new Node(4);
    tree.root.left.right = new Node(12);
    tree.root.left.right.left = new Node(10);
    tree.root.left.right.right = new Node(14);
    tree.root.right = new Node(22);
    tree.root.right.right = new Node(25);
    tree.printBoundary(tree.root);
}
}

Boundary Traversal of binary tree


问:
Blazor modifying a string (toUpper) fails
I'm doing some testing with Blazor and wanted to take a string and simply change it to uppercase as follows:

```<code>@page "/InputBindingTest"
<h1>Binding examples...</h1>
<hr />

<h2>Text input example:</h2>
<p>Firing the 'oninput' event for each key press</p>

<input type="text" bind-value-oninput="@CurrentText" />

<p>Current value is: @CurrentText</p>

<p>Here it is again in UPPERCASE: @CurrentText.ToUpper()</p>

<h2>Checkbox example:</h2>
<input name="check1" type="checkbox" bind-value-onchange="@CurrentSetting" />
<label for="check1">@CurrentSetting</label>

@functions {
    private string CurrentText { get; set; }
    private bool CurrentSetting { get; set; }
}
</code>```

Everything works except the ToUpper method on the string. Web Assembly takes a nasty dive:

WASM: Unhandled exception rendering component

I suppose this can't be done (yet) or am I doing something wrong?

答:
A careful look at the generated error trace reveals this is about a null reference exception.

The simple fix is a ?. :

```<code><p>Here it is again in UPPERCASE: @CurrentText?.ToUpper()</p>
</code>```

and/or

```<code>private string CurrentText { get; set; } = "";
</code>```

Blazor's binding can handle a null in @CurrentText
 just fine.

But ToUpper() can't be called on a null string.

Body:
I'm doing some testing with Blazor and wanted to take a string and simply change it to uppercase as follows:

@page "/InputBindingTest"

Binding examples...

Text input example:

Firing the 'oninput' event for each key press

<input type="text" bind-value-oninput="@CurrentText" />

Current value is: @CurrentText

Here it is again in UPPERCASE: @CurrentText.ToUpper()

Checkbox example:

<input name="check1" type="checkbox" bind-value-onchange="@CurrentSetting" />
@CurrentSetting

@functions {
    private string CurrentText { get; set; }
    private bool CurrentSetting { get; set; }
}

Everything works except the ToUpper method on the string. Web Assembly takes a nasty dive:

WASM: Unhandled exception rendering component

I suppose this can't be done (yet) or am I doing something wrong?

Body:
A careful look at the generated error trace reveals this is about a null reference exception.

The simple fix is a ?. :

<p>Here it is again in UPPERCASE: @CurrentText?.ToUpper()</p>

and/or

private string CurrentText { get; set; } = "";

Blazor's binding can handle a null in @CurrentText</p> just fine.

But ToUpper() can't be called on a null string.


问:
Ion.RangeSlider change status in Angular 7
I'm using Ion.RangeSlider in Angular7 project. When I want to update the slider I use following code:

```<code>var instance: any = $(".irs-hidden-input").data("ionRangeSlider");

        instance.update({
            from: Math.floor(Math.random() * (10)),
            to: 10
        });
</code>```

The $ sign is like to jQuery mode, How I can read data from @ViewChild?

Thanks for taking the time and explain it.

答:
I will recommend to use ng2-ion-range-slider instead of Ion.RangeSlider. Because i was faced same kind of issues to catch the update and change events of Ion.RangeSlider in Angular then i found this one.

For npm installation and Imports, do follow ng2-ion-range-slider documentation

ng2-ion-range-slider now optimized for easy use as an importable Angular 2 Module and installable using npm and it is built on top of Ion.RangeSlider so that we can access all the features of it in easy way.

```<code><ion-range-slider #sliderElement
          type="double"
          [min]="myMinVar"
          max="100"
          from="28"
          from_min="10"
          from_max="30"
          from_shadow="true"
          to="40"
          to_min="40"
          to_max="90"
          to_shadow="true"
          grid="true"
          grid_num="10"
          prefix="Weight: "
          postfix=" million pounds"
          decorate_both="false"
          (onUpdate)="myOnUpdate($event)"
          (onChange)="myOnChange($event)"
          (onFinish)="myOnFinish($event)"></ion-range-slider>
</code>```

I have answered same kind of issue get value of ion-rangeslider in Angular check it once..

Body:
I'm using Ion.RangeSlider in Angular7 project. When I want to update the slider I use following code:

var instance: any = $(".irs-hidden-input").data("ionRangeSlider");

        instance.update({
            from: Math.floor(Math.random() * (10)),
            to: 10
        });

The $ sign is like to jQuery mode, How I can read data from @ViewChild?

Thanks for taking the time and explain it.

Body:
I will recommend to use ng2-ion-range-slider instead of Ion.RangeSlider. Because i was faced same kind of issues to catch the update and change events of Ion.RangeSlider in Angular then i found this one.

For npm installation and Imports, do follow ng2-ion-range-slider documentation

ng2-ion-range-slider now optimized for easy use as an importable Angular 2 Module and installable using npm and it is built on top of Ion.RangeSlider so that we can access all the features of it in easy way.

<ion-range-slider #sliderElement
          type="double"
          [min]="myMinVar"
          max="100"
          from="28"
          from_min="10"
          from_max="30"
          from_shadow="true"
          to="40"
          to_min="40"
          to_max="90"
          to_shadow="true"
          grid="true"
          grid_num="10"
          prefix="Weight: "
          postfix=" million pounds"
          decorate_both="false"
          (onUpdate)="myOnUpdate($event)"
          (onChange)="myOnChange($event)"
          (onFinish)="myOnFinish($event)"></ion-range-slider>

I have answered same kind of issue get value of ion-rangeslider in Angular check it once..


问:
How to splice an array within the state of a React Component
I am making a timesheet app. The index.js renders the table. The rows of the table are read from the children array. The children array reads the state to keep itself updated. AddRow() is working fine. DeleteRow() has some problem. I intend to fetch the parentNode id from the event, lookup the state's array, splice it and let children update itself - which in turn updates the render. So when a row is deleted, it is spliced from the state's array, and that in turn is updated in the children array, and that in turn is rendered. DeleteRow runs everything except the array.splice or indexOf part. I even tried a for loop, but it doesn't work. Is my approach correct?</p>

```<code>index.js
import React from "react";
import ReactDOM from "react-dom";
import HeaderAndFirstTableRow from "./headerandfirstrow";
import TableRow from "./tablerow";
import "./styles.css";

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = { noOfRows: [] };
    this.addRow = this.addRow.bind(this);
    this.deleteRow = this.deleteRow.bind(this);
    this.find = this.find.bind(this);
  }
  addRow() {
    let arr = this.state.noOfRows;
    let arrLength = arr.length;
    arr.push(arrLength + 1);
    this.setState({
      noOfRows: arr
    });
  }
  find(arr, id) {
    for (let i = 0; i < arr.length; i++) {
      if (arr[i] === id) {
        return i;
      }
    }
  }
  deleteRow(event) {
    let arr = this.state.noOfRows;
    let id = event.target.parentNode.id;
    let ix = arr.findIndex(id);
    arr.splice(ix, 1);
    this.setState({ noOfRows: arr });
  }
  render() {
    let children = [];
    for (let i = 0; i < this.state.noOfRows.length; i++) {
      children.push(
        <TableRow id={this.state.noOfRows.length} delete={this.deleteRow} />
      );
    }
    return (
      <HeaderAndFirstTableRow click={this.addRow}>
        {children}
      </HeaderAndFirstTableRow>
    );
  }
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

headerandfirstrow.js

import React from "react";

import "./styles.css";

export default function HeaderAndFirstTableRow(props) {
  function handler() {
    props.click();
  }
  return (
    <table>
      <tr>
        <th>Feature</th>
        <th>Phase</th>
        <th>Comments</th>
        <th>Monday</th>
        <th>Tuesday</th>
        <th>Wednesday</th>
        <th>Thursday</th>
        <th>Friday</th>
        <th>Saturday</th>
        <th>Sunday</th>
        <th onClick={handler}>+</th>
      </tr>

      {props.children}
    </table>
  );
}

tablerow.js
import React from "react";
import "./styles.css";
export default function TableRow(props) {
  function del(e) {
    props.delete(e);
  }
  return (
    <tr id={props.id}>
      <td />
      <td />
      <td />
      <td />
      <td />
      <td />
      <td />
      <td />
      <td />
      <td />
      <td onClick={del}>-</td>
    </tr>
  );
}
</code>```

答:
splice mutates original array, you should not mutate state,

You can change to this

```<code>deleteRow(event) {
    let arr = this.state.noOfRows;
    let id = event.target.parentNode.id;
    let filteredArray = arr.filter(val=> val !== id)
    this.setState({ noOfRows: filteredArray });
}
</code>```

Body:
I am making a timesheet app. The index.js renders the table. The rows of the table are read from the children array. The children array reads the state to keep itself updated. AddRow() is working fine. DeleteRow() has some problem. I intend to fetch the parentNode id from the event, lookup the state's array, splice it and let children update itself - which in turn updates the render. So when a row is deleted, it is spliced from the state's array, and that in turn is updated in the children array, and that in turn is rendered. DeleteRow runs everything except the array.splice or indexOf part. I even tried a for loop, but it doesn't work. Is my approach correct?

index.js
import React from "react";
import ReactDOM from "react-dom";
import HeaderAndFirstTableRow from "./headerandfirstrow";
import TableRow from "./tablerow";
import "./styles.css";

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = { noOfRows: [] };
    this.addRow = this.addRow.bind(this);
    this.deleteRow = this.deleteRow.bind(this);
    this.find = this.find.bind(this);
  }
  addRow() {
    let arr = this.state.noOfRows;
    let arrLength = arr.length;
    arr.push(arrLength + 1);
    this.setState({
      noOfRows: arr
    });
  }
  find(arr, id) {
    for (let i = 0; i < arr.length; i++) {
      if (arr[i] === id) {
        return i;
      }
    }
  }
  deleteRow(event) {
    let arr = this.state.noOfRows;
    let id = event.target.parentNode.id;
    let ix = arr.findIndex(id);
    arr.splice(ix, 1);
    this.setState({ noOfRows: arr });
  }
  render() {
    let children = [];
    for (let i = 0; i < this.state.noOfRows.length; i++) {
      children.push(
        <TableRow id={this.state.noOfRows.length} delete={this.deleteRow} />
      );
    }
    return (
      <HeaderAndFirstTableRow click={this.addRow}>
        {children}
      </HeaderAndFirstTableRow>
    );
  }
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

headerandfirstrow.js

import React from "react";

import "./styles.css";

export default function HeaderAndFirstTableRow(props) {
  function handler() {
    props.click();
  }
  return (

        Feature
        Phase
        Comments
        Monday
        Tuesday
        Wednesday
        Thursday
        Friday
        Saturday
        Sunday
        +

      {props.children}

  );
}

tablerow.js
import React from "react";
import "./styles.css";
export default function TableRow(props) {
  function del(e) {
    props.delete(e);
  }
  return (

      -

  );
}

Body:
splice mutates original array, you should not mutate state,

You can change to this

deleteRow(event) {
    let arr = this.state.noOfRows;
    let id = event.target.parentNode.id;
    let filteredArray = arr.filter(val=> val !== id)
    this.setState({ noOfRows: filteredArray });
}


问:
ADMIN-DUPLICATECONFIGITEM: data base resource “hrhub-content” already content database “element- attribute-range-index
I am trying to create a script to add element- attribute-range-index and element –range-index from a config  file . please find below the script for the same.
I am able to add  element-range-index but not able to add element- attribute-range-index  via the script or through the admin console UI also .

Note: I have cross-checked and there is no duplicate index available for this . I have freshly created .Still facing the same issue.

```<code>import module namespace admin :="http://marklogic.com/xdmp/admin"
                                 at "/MarkLogic/admin.xqy"

let $dbid   := xdmp:database("hrhub-content")
let $config :=admin:get-configuration()
let $rangespec:= admin:database-range-element-attribute-index("string","www.aetna.com/hrhub/nm","plocalname","","pname","",fn:false())

return
 let $new-index  := admin:database-add-range-element-attribute-index($config,$dbid,$rangespec)
return admin:save-configuration-without-restart($new-index)
</code>```

Error message: ADMIN-DUPLICATECONFIGITEM: (ERR:FOER0000) data base
  resource “hrhub-content” already content database “element-
  attribute-range-index”

答:
I just tried the code that Wagner had pasted with the one change being

let $dbid   := xdmp:database("*Documents*")

and it worked. When I rerun the code I get the error that you are seeing ADMIN-DUPLICATECONFIGITEM, which makes sense since the index is already present. You may want to check if the index exists via this code -

```<code>xquery version "1.0-ml";
import module namespace admin = "http://marklogic.com/xdmp/admin" at "/MarkLogic/admin.xqy";

let $dbid   := xdmp:database("Documents")
let $config := admin:get-configuration()

return admin:database-get-range-element-attribute-indexes(
   $config,
   $dbid)
</code>```

Body:
I am trying to create a script to add element- attribute-range-index and element –range-index from a config  file . please find below the script for the same.
I am able to add  element-range-index but not able to add element- attribute-range-index  via the script or through the admin console UI also .

Note: I have cross-checked and there is no duplicate index available for this . I have freshly created .Still facing the same issue.

import module namespace admin :="http://marklogic.com/xdmp/admin"
                                 at "/MarkLogic/admin.xqy"

let $dbid   := xdmp:database("hrhub-content")
let $config :=admin:get-configuration()
let $rangespec:= admin:database-range-element-attribute-index("string","www.aetna.com/hrhub/nm","plocalname","","pname","",fn:false())

return
 let $new-index  := admin:database-add-range-element-attribute-index($config,$dbid,$rangespec)
return admin:save-configuration-without-restart($new-index)

Error message: ADMIN-DUPLICATECONFIGITEM: (ERR:FOER0000) data base
  resource “hrhub-content” already content database “element-
  attribute-range-index”

Body:
I just tried the code that Wagner had pasted with the one change being

let $dbid   := xdmp:database("*Documents*")

and it worked. When I rerun the code I get the error that you are seeing ADMIN-DUPLICATECONFIGITEM, which makes sense since the index is already present. You may want to check if the index exists via this code -

xquery version "1.0-ml";
import module namespace admin = "http://marklogic.com/xdmp/admin" at "/MarkLogic/admin.xqy";

let $dbid   := xdmp:database("Documents")
let $config := admin:get-configuration()

return admin:database-get-range-element-attribute-indexes(
   $config,
   $dbid)


问:
Finding a Row between two Spreadsheets and then finding the Row containing a value from that first row
I have a script where it searches between two Spreadsheets Columns A and B for the first row that has different values.   However after it finds that row with the different values, I want it to get that row, get the value in Spreadsheet 1 and find that specific value in the Spreadsheet 2.  And then get the row of that value in Spreadsheet 2. I made this code that performs the first part well, but when i try to get the second part I can't seem to think of how to put it together.

```<code>function checkAndPlace() {
  var sos = SpreadsheetApp.openById("Spreadsheet 1");
  var sas = SpreadsheetApp.setActiveSpreadsheet(sos);
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var s1 = ss.getActiveSheet();
  ss.getRange('F2').setValue('RUNNING')
  var Avals = s1.getRange("A1:A").getValues();
  var Alast1 = Avals.filter(String).length;
  var s1LastRow = s1.getLastRow()+1;
  var Sheet1DataRange = s1.getRange(1,1,s1LastRow,2);
  var Sheet1BDataRange = s1.getRange(1,2,s1LastRow,1);
  var Sheet1Data = Sheet1DataRange.getValues();
  var Sheet1BData = Sheet1BDataRange.getValues();
  var Sheet1length = Sheet1Data.length;
  var sos2 = SpreadsheetApp.openById("Spreadsheet 2");
  var sas2 = SpreadsheetApp.setActiveSpreadsheet(sos2);
  var ss2 = SpreadsheetApp.getActiveSpreadsheet();
  var s2 = ss2.getActiveSheet();
  var Avals2 = s2.getRange("A1:A").getValues();
  var Alast2 = Avals2.filter(String).length;
  var s2LastRow = s2.getLastRow()+1;
  var Sheet2DataRange = s2.getRange(1,1,s2LastRow,2);
  var Sheet2BDataRange = s2.getRange(1,2,s2LastRow,1);
  var Sheet2Data = Sheet2DataRange.getValues();
  var Sheet2BData = Sheet2BDataRange.getValues();
  var Sheet2length = Sheet2Data.length;
  for (var i = 0; i < Sheet1Data.length; i++) {
    var s1data = Sheet1Data[i][0];
    Logger.log(s1data)
    var s1Bdata = Sheet1BData[i][0];
    Logger.log(s1Bdata)
    var s2data = Sheet2Data[i][0];
    Logger.log(s2data)
    var s2Bdata = Sheet2BData[i][0];
    Logger.log(s2Bdata)
    if (s1data + s1Bdata != s2data + s2Bdata){
      var falseRow = i+1
      var falseRowARange = s2.getRange(falseRow,1,1,2);
      var falseRowAName = falseRowARange.getValues();
      var falseRowBRange = s2.getRange(falseRow,2,1,1);
      var falseRowBName = falseRowBRange.getValues();
      Logger.log("Line: "+i+". Sheets are NOT equal. Sheet1 = "+s1data+", Sheet2 = "+s2data);
      for (var j = 0; j < Sheet2Data.length; j++) {
        var s1data = Sheet1Data[j][0];
        Logger.log(s1data)
        var s1Bdata = Sheet1BData[j][0];
        Logger.log(s1Bdata)
!!!!        var falsejdata = falseRowAName[j][0]; "Cannot read property 0"
        Logger.log(falsejdata)
        var falsejBdata = falseRowBName[j][0];
        Logger.log(falsejBdata)
        if(falsejdata + falsejBdata == s1data + s1Bdata) {
          var trueRow = j+1
          Logger.log(trueRow)
        }
    }
      return false;
    }
    else {
      Logger.log("Line: "+i+". Sheets are equal, value: "+s1data);
    }
  }
}
</code>```

it keeps reading "cannot read property '0' from undefined."  I marked the line in the code where it shows this.

The reason I'm trying to do this is because I have a spreadsheet that keeps getting updated with more information and I need to know what rows were updated in order to have the script add cells to those rows with information. So Spreadsheet 1 compares it self to a mirror spreadsheet 2.  It finds which values are different and then decides to delete or add a row.  But determining which one for it to do has been an issue.  I first made it add or delete if it was bigger or smaller than the mirror sheet. But if it gets updated very quickly, it finds it self deleting rows it's suppose to add and gets everything out of wack.  So I decided I want the value from the different row from spreadsheet 1 to find that value in spreadsheet 2 to determine if it should be deleted, added, or start the checkAndPlace() function from the start instead of doing anything. I then want to find the value from the different row from spreadsheet 2 to search for itself in spreadsheet 1 to see if it still exists in there or not and which row?  so it can compare the difference of the rows it exists in.

But right now I don't even know if I need two different loops to make this work or how to even right it out.  Just looking at my code, you can see how it got all kinds of confusing. I am relatively new, so maybe there's something simple I overlooked or didn't know about.

Edit: Another piece of information is that Spreadsheet 1 gets information fed into it from a query coming from a spreadsheet that is edited multiple times a day.  This edit causes an install-able onChange() function to run the checkAndPlace() function.

答:
Nevermind, I think I got it. came up with the values I was expecting to see. </p>

```<code> for (var i = 0; i < Sheet1Data.length; i++) {
    var s1data = Sheet1Data[i][0];// s1 is spreadsheet 1's sheet.
    Logger.log(s1data)
    var s1Bdata = Sheet1BData[i][0];
    Logger.log(s1Bdata)
    var s2data = Sheet2Data[i][0];
    Logger.log(s2data)
    var s2Bdata = Sheet2BData[i][0];
    Logger.log(s2Bdata)
    if (s1data + s1Bdata != s2data + s2Bdata){
      var falseRow = i+1
      var falseRow2ARange = s2.getRange(falseRow,1,1,1);//s2 is spreadsheet 2's sheet.
      var falseRow2AName = falseRow2ARange.getValues();
      var falseRow2BRange = s2.getRange(falseRow,2,1,1);
      var falseRow2BName = falseRow2BRange.getValues();
      Logger.log('falseRow is '+falseRow+' and its value is '+falseRow2AName+' '+falseRow2BName+'.');
      Logger.log("Line: "+i+". Sheets are NOT equal. Sheet1 = "+s1data+", Sheet2 = "+s2data);
      for (var j = 0; j < Sheet1Data.length; j++) {
        var s1data = Sheet1Data[j][0];
        Logger.log(s1data)
        var s1Bdata = Sheet1BData[j][0];
        Logger.log(s1Bdata)
        if(falseRow2AName + falseRow2BName == s1data + s1Bdata) {
          var trueRow = j+1
          Logger.log(trueRow)
        }
}
}
}
</code>```

Body:
I have a script where it searches between two Spreadsheets Columns A and B for the first row that has different values.   However after it finds that row with the different values, I want it to get that row, get the value in Spreadsheet 1 and find that specific value in the Spreadsheet 2.  And then get the row of that value in Spreadsheet 2. I made this code that performs the first part well, but when i try to get the second part I can't seem to think of how to put it together.

function checkAndPlace() {
  var sos = SpreadsheetApp.openById("Spreadsheet 1");
  var sas = SpreadsheetApp.setActiveSpreadsheet(sos);
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var s1 = ss.getActiveSheet();
  ss.getRange('F2').setValue('RUNNING')
  var Avals = s1.getRange("A1:A").getValues();
  var Alast1 = Avals.filter(String).length;
  var s1LastRow = s1.getLastRow()+1;
  var Sheet1DataRange = s1.getRange(1,1,s1LastRow,2);
  var Sheet1BDataRange = s1.getRange(1,2,s1LastRow,1);
  var Sheet1Data = Sheet1DataRange.getValues();
  var Sheet1BData = Sheet1BDataRange.getValues();
  var Sheet1length = Sheet1Data.length;
  var sos2 = SpreadsheetApp.openById("Spreadsheet 2");
  var sas2 = SpreadsheetApp.setActiveSpreadsheet(sos2);
  var ss2 = SpreadsheetApp.getActiveSpreadsheet();
  var s2 = ss2.getActiveSheet();
  var Avals2 = s2.getRange("A1:A").getValues();
  var Alast2 = Avals2.filter(String).length;
  var s2LastRow = s2.getLastRow()+1;
  var Sheet2DataRange = s2.getRange(1,1,s2LastRow,2);
  var Sheet2BDataRange = s2.getRange(1,2,s2LastRow,1);
  var Sheet2Data = Sheet2DataRange.getValues();
  var Sheet2BData = Sheet2BDataRange.getValues();
  var Sheet2length = Sheet2Data.length;
  for (var i = 0; i < Sheet1Data.length; i++) {
    var s1data = Sheet1Data[i][0];
    Logger.log(s1data)
    var s1Bdata = Sheet1BData[i][0];
    Logger.log(s1Bdata)
    var s2data = Sheet2Data[i][0];
    Logger.log(s2data)
    var s2Bdata = Sheet2BData[i][0];
    Logger.log(s2Bdata)
    if (s1data + s1Bdata != s2data + s2Bdata){
      var falseRow = i+1
      var falseRowARange = s2.getRange(falseRow,1,1,2);
      var falseRowAName = falseRowARange.getValues();
      var falseRowBRange = s2.getRange(falseRow,2,1,1);
      var falseRowBName = falseRowBRange.getValues();
      Logger.log("Line: "+i+". Sheets are NOT equal. Sheet1 = "+s1data+", Sheet2 = "+s2data);
      for (var j = 0; j < Sheet2Data.length; j++) {
        var s1data = Sheet1Data[j][0];
        Logger.log(s1data)
        var s1Bdata = Sheet1BData[j][0];
        Logger.log(s1Bdata)
!!!!        var falsejdata = falseRowAName[j][0]; "Cannot read property 0"
        Logger.log(falsejdata)
        var falsejBdata = falseRowBName[j][0];
        Logger.log(falsejBdata)
        if(falsejdata + falsejBdata == s1data + s1Bdata) {
          var trueRow = j+1
          Logger.log(trueRow)
        }
    }
      return false;
    }
    else {
      Logger.log("Line: "+i+". Sheets are equal, value: "+s1data);
    }
  }
}

it keeps reading "cannot read property '0' from undefined."  I marked the line in the code where it shows this.

The reason I'm trying to do this is because I have a spreadsheet that keeps getting updated with more information and I need to know what rows were updated in order to have the script add cells to those rows with information. So Spreadsheet 1 compares it self to a mirror spreadsheet 2.  It finds which values are different and then decides to delete or add a row.  But determining which one for it to do has been an issue.  I first made it add or delete if it was bigger or smaller than the mirror sheet. But if it gets updated very quickly, it finds it self deleting rows it's suppose to add and gets everything out of wack.  So I decided I want the value from the different row from spreadsheet 1 to find that value in spreadsheet 2 to determine if it should be deleted, added, or start the checkAndPlace() function from the start instead of doing anything. I then want to find the value from the different row from spreadsheet 2 to search for itself in spreadsheet 1 to see if it still exists in there or not and which row?  so it can compare the difference of the rows it exists in.

But right now I don't even know if I need two different loops to make this work or how to even right it out.  Just looking at my code, you can see how it got all kinds of confusing. I am relatively new, so maybe there's something simple I overlooked or didn't know about.

Edit: Another piece of information is that Spreadsheet 1 gets information fed into it from a query coming from a spreadsheet that is edited multiple times a day.  This edit causes an install-able onChange() function to run the checkAndPlace() function.

Body:
Nevermind, I think I got it. came up with the values I was expecting to see.

 for (var i = 0; i < Sheet1Data.length; i++) {
    var s1data = Sheet1Data[i][0];// s1 is spreadsheet 1's sheet.
    Logger.log(s1data)
    var s1Bdata = Sheet1BData[i][0];
    Logger.log(s1Bdata)
    var s2data = Sheet2Data[i][0];
    Logger.log(s2data)
    var s2Bdata = Sheet2BData[i][0];
    Logger.log(s2Bdata)
    if (s1data + s1Bdata != s2data + s2Bdata){
      var falseRow = i+1
      var falseRow2ARange = s2.getRange(falseRow,1,1,1);//s2 is spreadsheet 2's sheet.
      var falseRow2AName = falseRow2ARange.getValues();
      var falseRow2BRange = s2.getRange(falseRow,2,1,1);
      var falseRow2BName = falseRow2BRange.getValues();
      Logger.log('falseRow is '+falseRow+' and its value is '+falseRow2AName+' '+falseRow2BName+'.');
      Logger.log("Line: "+i+". Sheets are NOT equal. Sheet1 = "+s1data+", Sheet2 = "+s2data);
      for (var j = 0; j < Sheet1Data.length; j++) {
        var s1data = Sheet1Data[j][0];
        Logger.log(s1data)
        var s1Bdata = Sheet1BData[j][0];
        Logger.log(s1Bdata)
        if(falseRow2AName + falseRow2BName == s1data + s1Bdata) {
          var trueRow = j+1
          Logger.log(trueRow)
        }
}
}
}


问:
How do I access class variable?
```<code>class TestController < ApplicationController

  def test
    @goodbay = TestClass.varible
  end
end

class TestClass
  @@varible = "var"
end
</code>```

and i get error

```<code>undefined method 'varible' for TestClass:Class
</code>```

on the line @goodbay = TestClass.varible

What is wrong?

答:
here's another option:

class RubyList
  @@geek = "Matz"
  @@country = 'USA'
end
RubyList.class_variable_set(:@@geek, 'Matz rocks!')
puts RubyList.class_variable_get(:@@geek)
```

Title: How do I access class variable?

Body:
class TestController < ApplicationController

  def test
    @goodbay = TestClass.varible
  end
end

class TestClass
  @@varible = "var"
end

and i get error

undefined method 'varible' for TestClass:Class

on the line @goodbay = TestClass.varible

What is wrong?


答:
Use indexOf instead of findIndex.
Additionally, always copy objects instead of mutating them directly into the state.

Here is working Fiddle:
https://stackblitz.com/edit/react-6hfnww

Title: How to splice an array within the state of a React Component


答:
Splicing this.state.noOfRows array mutates its elements in place.

In deleteRows, this is setting the same array which is now mutated back in the component state.

Instead use Array.prototype.slice to get chunks of the array without the item and compose a new array from that.

```<code>  deleteRow(event) {
    let arr = this.state.noOfRows;
    let id = event.target.parentNode.id;
    let ix = arr.findIndex(id);
    const noOfRows = [...arr.slice(0, ix), ...arr.slice(ix+1)] ;
    this.setState({ noOfRows });
  }
</code>```

Body:
Splicing this.state.noOfRows array mutates its elements in place.

In deleteRows, this is setting the same array which is now mutated back in the component state.

Instead use Array.prototype.slice to get chunks of the array without the item and compose a new array from that.

  deleteRow(event) {
    let arr = this.state.noOfRows;
    let id = event.target.parentNode.id;
    let ix = arr.findIndex(id);
    const noOfRows = [...arr.slice(0, ix), ...arr.slice(ix+1)] ;
    this.setState({ noOfRows });
  }