问:
Add event click into marker openlayers
Good day, I'm trying to add events to dynamically programmed markers on a map. The markers do show on the screen but when you click to show a div, instead of just showing the div related to the bookmark, activate the event click on all the div on the screen.

Where the marker is created is when invoking the function crearMarcadores and send the coordinates and the variable cc to use for the id of the div.

```<code>var centro = ol.extent.getCenter(boundingBox);
crearMarcadores(centro, cc);
</code>```

The divs if you create them correctly, as I understand it must be a div for each marker.

And where I'm almost sure is my mistake is in:

```<code>  var feature = map.forEachFeatureAtPixel(evt.pixel,
        function(feature, layer) {
            return feature;
  });
</code>```

Since it executes a foreach, and should only return the marker feature. But I do not know how to run it only in the current marker. Although all the examples I have found are with foreach.

For your valuable help, thank you very much.

    var iconFeature = new ol.Feature({
        geometry: new ol.geom.Point([-90.204114, 13.866291]),
        name: 'nombre',
        population: 4000,
        rainfall: 500
    });

    var iconStyle = new ol.style.Style({
        image: new ol.style.Icon( /** @type {olx.style.IconOptions} */ ({
     anchor: [0.5, 46],
     anchorXUnits: 'fraction',
     anchorYUnits: 'pixels',
     opacity: 0.75,
     src: 'http://openlayers.org/en/v3.9.0/examples/data/icon.png'
        }))
    });
    iconFeature.setStyle(iconStyle);

    var vectorSource = new ol.source.Vector({
        features: [iconFeature]
    });

    var vectorLayer = new ol.layer.Vector({
     source: vectorSource
    });

    var layer = new ol.layer.Vector({ /*layer con los poligonos*/
        source: new ol.source.Vector()
    })

    function crearMarcadores(centroPoligono, CentroCosto) {

        var iconFeature = new ol.Feature({
         geometry: new ol.geom.Point(centroPoligono),
         name: CentroCosto,
         population: 4000,
         rainfall: 500
        });
        vectorSource.addFeature(iconFeature);
        iconFeature.setStyle(iconStyle);

        //------------start creation popup
        var div = document.createElement('div');
        div.setAttribute("id", CentroCosto);
        div.setAttribute("style", "width: 580px; height: 400px; float: left");
        document.body.appendChild(div);

        var element = document.getElementById(CentroCosto);

        var popup = new ol.Overlay({
         element: element,
         positioning: 'bottom-center',
         stopEvent: false
        });
        map.addOverlay(popup);
        //------------end creation popup

        // --------------display popup on click
        map.on('click', function(evt) {

     var feature = map.forEachFeatureAtPixel(evt.pixel,
      function(feature, layer) {
       return feature;
      });
     if (feature) {
      var geometry = feature.getGeometry();
      var coord = geometry.getCoordinates();
      popup.setPosition(coord);
      $(element).popover({
       'placement': 'top',
       'html': true,
       'content': feature.get('name')
      });
      $(element).popover('show');
     } else {
      $(element).popover('destroy');
     }
        });
    //---------------end display popup on click

    } //termina funcion crearMarcadores

    function generarMapas() {

    var FechaInicial = '';
    var FechaFinal = '';
    var Finca = '';
    $.ajax({
     type: "POST",
     url: "FrmMapaAvanceRiego.aspx\/FillMapas",
     data: '{FechaInicial: "' + FechaInicial + '", FechaFinal: "' + FechaFinal + '", Finca: "' + Finca + '"}',
     contentType: "application/json; charset=utf-8",
     dataType: "json",
     success: function(msg) {
      var data = JSON.parse(msg.d);
      coordenadas = [];
      cc = [];
      $.each(data, function(i, item) {
       coordenadas[i] = item.Coordenadas;
       cc[i] = item.CentroDeCostoLote;
       crearPoligonos(coordenadas[i], cc[i]);

      });
     },
     error: errores
    });
    }

    function errores(msg) {
     alert('Error: ' + msg.responseText);
    }

    function crearPoligonos(coordenada, cc) {
    //console.log(coordenada);
    console.log(cc);
    var coordenadas = coordenada.split(' ') // Separamos por espacio
     .map(function(data) {
      var info = data.split(','), // Separamos por coma
       coord = { // Creamos el obj de coordenada
        lat: parseFloat(info[1]),
        lng: parseFloat(info[0])
       };

      return coord;
     });

    var parserJSTS = new jsts.io.OL3Parser();

    var poly = new ol.Feature({
     geometry: new ol.geom.Polygon([coordenadas.map(function(_ref) {
      var lng = _ref.lng,
       lat = _ref.lat;
      return [lng, lat];
     })])
    });

    var boundingBox = poly.getGeometry().getExtent()
    var polybbox = new ol.Feature({
     geometry: ol.geom.Polygon.fromExtent(boundingBox)
    })

    var [xmin, ymin, xmax, ymax] = boundingBox

    var porcentaje = 0.50
    var newXmax = xmin + ((xmax - xmin) * porcentaje)

    var newBoundingBox = [xmin, ymin, newXmax, ymax]

    var polybbox50 = new ol.Feature({
     geometry: ol.geom.Polygon.fromExtent(newBoundingBox)
    })

    var polybbox50jsts = parserJSTS.read(polybbox50.getGeometry())

    var polyjsts = parserJSTS.read(poly.getGeometry())

    var intersectionJSTSGeometry = polyjsts.intersection(polybbox50jsts)

    var intersectionGeometry = parserJSTS.write(intersectionJSTSGeometry)

    var newPoly = new ol.Feature({
     geometry: intersectionGeometry
    })
    //console.log(boundingBox)

    newPoly.setStyle(new ol.style.Style({
     fill: new ol.style.Fill({
      color: '#02ABFF'
     })
    }))

    // Descomentar para ver los bounding boxes
    //      layer.getSource().addFeature(polybbox)
    //      layer.getSource().addFeature(polybbox50)
    layer.getSource().addFeature(poly)
    layer.getSource().addFeature(newPoly)

    var centro = ol.extent.getCenter(boundingBox);
    //console.log(centro);

    crearMarcadores(centro, cc);
    }

    //------------start creation map
    var map = new ol.Map({
    layers: [
     new ol.layer.Tile({
      source: new ol.source.BingMaps({
       key:
    'AudCyoI6al0eAZmQhwmI1IG9AOdGH8DHHk6PsiGta1faEACulxawFU9KV-XAvZ8f',
       imagerySet: 'AerialWithLabels'
      })
     }),
     layer, vectorLayer
    ],
    target: 'map',
    controls: ol.control.defaults({
     attributionOptions: ({
      collapsible: false
     })
    }),
    view: new ol.View({
     center: [-90.365730, 13.954185],
     zoom: 9,
     projection: 'EPSG:4326'
    })
    });
    // --------------end creation map```
<pre class="snippet-code-html lang-html prettyprint-override"><code><link href="https://openlayers.org/en/v4.5.0/css/ol.css" rel="stylesheet"/>
<script src="https://openlayers.org/en/v4.5.0/build/ol.js"></script>
<script
  src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.19.2/moment.min.js"></script>

    <div id="map" class="map" tabindex="0">
    </div>
    <div id="popup"></div>
    </code>```

答:
forEachFeatureAtPixel (api doc) goes through every feature of every layer at that location. So you might get unexpected results from other layers.

But the function also let's you define a layerFilter which decides if you want to include a layer or not.

Example:

```<code>map.addLayer(new ol.layer.Vector({
  source: vectorSource1,
  myKey: 'magic' // arbitrary property to distinguish between the layers
});

map.addLayer(new ol.layer.Vector({
  source: vectorSource2,
  myKey: 'someotherlayer'
});

// this only gives back the first feature at this position
// on the layer with the property `myKey` equal to `'magic'`
const feature = map.forEachFeatureAtPixel(
  pixel,
  function(someFeature){ return someFeature; }, // stop at the very first feature
  {
    layerFilter: function(layer) { return layer.get('myKey') === 'magic'; }
  }
);
</code>```

Title: Add event click into marker openlayers

Body:
Good day, I'm trying to add events to dynamically programmed markers on a map. The markers do show on the screen but when you click to show a div, instead of just showing the div related to the bookmark, activate the event click on all the div on the screen.

Where the marker is created is when invoking the function crearMarcadores and send the coordinates and the variable cc to use for the id of the div.

var centro = ol.extent.getCenter(boundingBox);
crearMarcadores(centro, cc);

The divs if you create them correctly, as I understand it must be a div for each marker.

And where I'm almost sure is my mistake is in:

  var feature = map.forEachFeatureAtPixel(evt.pixel,
        function(feature, layer) {
            return feature;
  });

Since it executes a foreach, and should only return the marker feature. But I do not know how to run it only in the current marker. Although all the examples I have found are with foreach.

For your valuable help, thank you very much.

    var iconFeature = new ol.Feature({
        geometry: new ol.geom.Point([-90.204114, 13.866291]),
        name: 'nombre',
        population: 4000,
        rainfall: 500
    });

    var iconStyle = new ol.style.Style({
        image: new ol.style.Icon( /** @type {olx.style.IconOptions} */ ({
     anchor: [0.5, 46],
     anchorXUnits: 'fraction',
     anchorYUnits: 'pixels',
     opacity: 0.75,
     src: 'http://openlayers.org/en/v3.9.0/examples/data/icon.png'
        }))
    });
    iconFeature.setStyle(iconStyle);

    var vectorSource = new ol.source.Vector({
        features: [iconFeature]
    });

    var vectorLayer = new ol.layer.Vector({
     source: vectorSource
    });

    var layer = new ol.layer.Vector({ /*layer con los poligonos*/
        source: new ol.source.Vector()
    })

    function crearMarcadores(centroPoligono, CentroCosto) {

        var iconFeature = new ol.Feature({
         geometry: new ol.geom.Point(centroPoligono),
         name: CentroCosto,
         population: 4000,
         rainfall: 500
        });
        vectorSource.addFeature(iconFeature);
        iconFeature.setStyle(iconStyle);

        //------------start creation popup
        var div = document.createElement('div');
        div.setAttribute("id", CentroCosto);
        div.setAttribute("style", "width: 580px; height: 400px; float: left");
        document.body.appendChild(div);

        var element = document.getElementById(CentroCosto);

        var popup = new ol.Overlay({
         element: element,
         positioning: 'bottom-center',
         stopEvent: false
        });
        map.addOverlay(popup);
        //------------end creation popup

        // --------------display popup on click
        map.on('click', function(evt) {

     var feature = map.forEachFeatureAtPixel(evt.pixel,
      function(feature, layer) {
       return feature;
      });
     if (feature) {
      var geometry = feature.getGeometry();
      var coord = geometry.getCoordinates();
      popup.setPosition(coord);
      $(element).popover({
       'placement': 'top',
       'html': true,
       'content': feature.get('name')
      });
      $(element).popover('show');
     } else {
      $(element).popover('destroy');
     }
        });
    //---------------end display popup on click

    } //termina funcion crearMarcadores

    function generarMapas() {

    var FechaInicial = '';
    var FechaFinal = '';
    var Finca = '';
    $.ajax({
     type: "POST",
     url: "FrmMapaAvanceRiego.aspx\/FillMapas",
     data: '{FechaInicial: "' + FechaInicial + '", FechaFinal: "' + FechaFinal + '", Finca: "' + Finca + '"}',
     contentType: "application/json; charset=utf-8",
     dataType: "json",
     success: function(msg) {
      var data = JSON.parse(msg.d);
      coordenadas = [];
      cc = [];
      $.each(data, function(i, item) {
       coordenadas[i] = item.Coordenadas;
       cc[i] = item.CentroDeCostoLote;
       crearPoligonos(coordenadas[i], cc[i]);

      });
     },
     error: errores
    });
    }

    function errores(msg) {
     alert('Error: ' + msg.responseText);
    }

    function crearPoligonos(coordenada, cc) {
    //console.log(coordenada);
    console.log(cc);
    var coordenadas = coordenada.split(' ') // Separamos por espacio
     .map(function(data) {
      var info = data.split(','), // Separamos por coma
       coord = { // Creamos el obj de coordenada
        lat: parseFloat(info[1]),
        lng: parseFloat(info[0])
       };

      return coord;
     });

    var parserJSTS = new jsts.io.OL3Parser();

    var poly = new ol.Feature({
     geometry: new ol.geom.Polygon([coordenadas.map(function(_ref) {
      var lng = _ref.lng,
       lat = _ref.lat;
      return [lng, lat];
     })])
    });

    var boundingBox = poly.getGeometry().getExtent()
    var polybbox = new ol.Feature({
     geometry: ol.geom.Polygon.fromExtent(boundingBox)
    })

    var [xmin, ymin, xmax, ymax] = boundingBox

    var porcentaje = 0.50
    var newXmax = xmin + ((xmax - xmin) * porcentaje)

    var newBoundingBox = [xmin, ymin, newXmax, ymax]

    var polybbox50 = new ol.Feature({
     geometry: ol.geom.Polygon.fromExtent(newBoundingBox)
    })

    var polybbox50jsts = parserJSTS.read(polybbox50.getGeometry())

    var polyjsts = parserJSTS.read(poly.getGeometry())

    var intersectionJSTSGeometry = polyjsts.intersection(polybbox50jsts)

    var intersectionGeometry = parserJSTS.write(intersectionJSTSGeometry)

    var newPoly = new ol.Feature({
     geometry: intersectionGeometry
    })
    //console.log(boundingBox)

    newPoly.setStyle(new ol.style.Style({
     fill: new ol.style.Fill({
      color: '#02ABFF'
     })
    }))

    // Descomentar para ver los bounding boxes
    //      layer.getSource().addFeature(polybbox)
    //      layer.getSource().addFeature(polybbox50)
    layer.getSource().addFeature(poly)
    layer.getSource().addFeature(newPoly)

    var centro = ol.extent.getCenter(boundingBox);
    //console.log(centro);

    crearMarcadores(centro, cc);
    }

    //------------start creation map
    var map = new ol.Map({
    layers: [
     new ol.layer.Tile({
      source: new ol.source.BingMaps({
       key:
    'AudCyoI6al0eAZmQhwmI1IG9AOdGH8DHHk6PsiGta1faEACulxawFU9KV-XAvZ8f',
       imagerySet: 'AerialWithLabels'
      })
     }),
     layer, vectorLayer
    ],
    target: 'map',
    controls: ol.control.defaults({
     attributionOptions: ({
      collapsible: false
     })
    }),
    view: new ol.View({
     center: [-90.365730, 13.954185],
     zoom: 9,
     projection: 'EPSG:4326'
    })
    });
    // --------------end creation map

<link href="https://openlayers.org/en/v4.5.0/css/ol.css" rel="stylesheet"/>

Body:
forEachFeatureAtPixel (api doc) goes through every feature of every layer at that location. So you might get unexpected results from other layers.

But the function also let's you define a layerFilter which decides if you want to include a layer or not.

Example:

map.addLayer(new ol.layer.Vector({
  source: vectorSource1,
  myKey: 'magic' // arbitrary property to distinguish between the layers
});

map.addLayer(new ol.layer.Vector({
  source: vectorSource2,
  myKey: 'someotherlayer'
});

// this only gives back the first feature at this position
// on the layer with the property `myKey` equal to `'magic'`
const feature = map.forEachFeatureAtPixel(
  pixel,
  function(someFeature){ return someFeature; }, // stop at the very first feature
  {
    layerFilter: function(layer) { return layer.get('myKey') === 'magic'; }
  }
);


来源: stackexchange

问:
How to automatically change text and pictures using a state machine in JavaScript
I have a character, "Pepe". My goal is to display Pepe's mood using a textbox for his state (his mood, "happy", "sad", etc.), another textbox for what he says, and an image that shows how he feels. What I want to do is change his current state with time. After a certain number of seconds, I want his state to change from "Happy" to "Sad", and then continue to change like a real living animal.   I have four states for Pepe: "Happy", "Sad", "Hungry" and "Angry". I have the JavaScript code below. In the HTML, I included buttons so if Pepe is "Hungry", a button can change Pepe from "Hungry" to "Happy". My problem is that I can't get the images to automatically change. I want it to be as random as possible. Any ideas?

```<code>var thePest

function pestConstructor(state,pepe,petimage,counter)
{

 this.state = state
    this.pepe = pepe
    this.petimage = petimage
    this.counter = counter
}
function startup()
{

 thePest = new pestConstructor("Happy","Hi!",
 "https://ih1.redbubble.net/image.141976807.7205/flat,800x800,075,t.jpg",0)

      display(thePest)
      setTimeout("Simulate(thePest)",1000)
}
function display(pest)
{

 var state = pest.state

 if( state == "Angry" )
      {
           pest.pepe = "AHHHH!!!"
           pest.petimage = "http://i0.kym-cdn.com/entries/icons/original/000/017/318/angry_pepe.jpg"
      }
      else if( state == "Happy" )
      {
           pest.pepe = "Hi!"
           pest.petimage = "https://ih1.redbubble.net/image.141976807.7205/flat,800x800,075,t.jpg"
      }
      else if( state == "Hungry" )
      {
           pest.pepe = "FOOD!"
           pest.petimage = "https://pbs.twimg.com/media/CS5XSd1UkAEfpUv.png"
      }
       else if( state == "Sad" )
      {
           pest.pepe = "I'm Sad"
           pest.petimage = "http://i0.kym-cdn.com/photos/images/original/000/945/016/648.png"
      }
      else
      {
          pest.petmood = "Dead"
      }

      document.getElementById("state").value = pest.state
      document.getElementById("pepe").value = pest.pepe
      document.getElementById("petimage").src = pest.petimage
      document.getElementById("counter").value = pest.counter
}
function Simulate(pest)
{

 pest.counter++
 var state = pest.state

      var n = Math.random(pest.state)

      if( state == "Happy" && n < 0.5 )
          pest.state = "Hungry"
      else if( state == "Hungry" && n < 0.4 )
          pest.state = "Angry"
      else if( state == "Angry" && n < 0.42 )
          pest.state = "Sad"
      else if( state == "Sad" && n < 0.43 )
          pest.state = "Sleepy"
      else if( state == "Sleepy" && n < 0.3 )
          pest.state = "Dead"

      display(thePest)
      setTimeout("Simulate(thePest)",1000)
}
function Feed(pest)
{

 var state = pest.state

  if( state == "Hungry" )
          pest.state = "Happy"

         display(thePest)
}
function Love(pest)
{

 var state = pest.state

  if( state == "Sad" )
          pest.state = "Happy"

         display(thePest)
}
function Mad(pest)
{

 var state = pest.state

  if( state == "Mad" )
          pest.state = "Happy"

         display(thePest)
}
function Annoy(pest)
{

 var state = pest.state

  if( state == "Happy" )
          pest.state = "Angry"

         display(thePest)
}
</script>`
</code>```

答:
The only problem i see is that you do not ever call the startup which fires up the whole process.

Update without using current state for randomness

var thePest

function pestConstructor(state, pepe, petimage, counter) {

  this.state = state
  this.pepe = pepe
  this.petimage = petimage
  this.counter = counter
}

function startup() {

  thePest = new pestConstructor("Happy", "Hi!",
    "https://ih1.redbubble.net/image.141976807.7205/flat,800x800,075,t.jpg", 0)

  display(thePest)
  setTimeout("Simulate(thePest)", 1000)
}

function display(pest) {

  var state = pest.state

  if (state == "Angry") {
    pest.pepe = "AHHHH!!!"
    pest.petimage = "http://i0.kym-cdn.com/entries/icons/original/000/017/318/angry_pepe.jpg"
  } else if (state == "Happy") {
    pest.pepe = "Hi!"
    pest.petimage = "https://ih1.redbubble.net/image.141976807.7205/flat,800x800,075,t.jpg"
  } else if (state == "Hungry") {
    pest.pepe = "FOOD!"
    pest.petimage = "https://pbs.twimg.com/media/CS5XSd1UkAEfpUv.png"
  } else if (state == "Sad") {
    pest.pepe = "I'm Sad"
    pest.petimage = "http://i0.kym-cdn.com/photos/images/original/000/945/016/648.png"
  } else {
    pest.petmood = "Dead"
  }

  document.getElementById("state").value = pest.state
  document.getElementById("pepe").value = pest.pepe
  document.getElementById("petimage").src = pest.petimage
  document.getElementById("counter").value = pest.counter
}

function Simulate(pest) {

  pest.counter++
    var state = pest.state

  var n = Math.random(pest.state)
  // assuming you want to stop when Dead
  if (pest.state !== "Dead") {
    if (state == "Sleepy" && n < 0.1)
      pest.state = "Dead"
    else if (n < 0.2)
      pest.state = "Hungry"
    else if (n < 0.3)
      pest.state = "Angry"
    else if (n < 0.4)
      pest.state = "Sad"
    else if (n < 0.5)
      pest.state = "Sleepy"

    display(thePest)
    setTimeout("Simulate(thePest)", 1000)
  }
}

function Feed(pest) {

  var state = pest.state

  if (state == "Hungry")
    pest.state = "Happy"

  display(thePest)
}

function Love(pest) {

  var state = pest.state

  if (state == "Sad")
    pest.state = "Happy"

  display(thePest)
}

function Mad(pest) {

  var state = pest.state

  if (state == "Mad")
    pest.state = "Happy"

  display(thePest)
}

function Annoy(pest) {

  var state = pest.state

  if (state == "Happy")
    pest.state = "Angry"

  display(thePest)
}

startup();```
<pre class="snippet-code-html lang-html prettyprint-override"><code>state: <input id="state"><br> pepe: <input id="pepe"><br> img: <img src="" id="petimage"><br> counter: <input id="counter"><br></code>```

Just a heads up: You have no display data for the Sleepy state.

ContentLicense: CC BY-SA 3.0

Body:
I have a character, "Pepe". My goal is to display Pepe's mood using a textbox for his state (his mood, "happy", "sad", etc.), another textbox for what he says, and an image that shows how he feels. What I want to do is change his current state with time. After a certain number of seconds, I want his state to change from "Happy" to "Sad", and then continue to change like a real living animal.   I have four states for Pepe: "Happy", "Sad", "Hungry" and "Angry". I have the JavaScript code below. In the HTML, I included buttons so if Pepe is "Hungry", a button can change Pepe from "Hungry" to "Happy". My problem is that I can't get the images to automatically change. I want it to be as random as possible. Any ideas?

var thePest

function pestConstructor(state,pepe,petimage,counter)
{

 this.state = state
    this.pepe = pepe
    this.petimage = petimage
    this.counter = counter
}
function startup()
{

 thePest = new pestConstructor("Happy","Hi!",
 "https://ih1.redbubble.net/image.141976807.7205/flat,800x800,075,t.jpg",0)

      display(thePest)
      setTimeout("Simulate(thePest)",1000)
}
function display(pest)
{

 var state = pest.state

 if( state == "Angry" )
      {
           pest.pepe = "AHHHH!!!"
           pest.petimage = "http://i0.kym-cdn.com/entries/icons/original/000/017/318/angry_pepe.jpg"
      }
      else if( state == "Happy" )
      {
           pest.pepe = "Hi!"
           pest.petimage = "https://ih1.redbubble.net/image.141976807.7205/flat,800x800,075,t.jpg"
      }
      else if( state == "Hungry" )
      {
           pest.pepe = "FOOD!"
           pest.petimage = "https://pbs.twimg.com/media/CS5XSd1UkAEfpUv.png"
      }
       else if( state == "Sad" )
      {
           pest.pepe = "I'm Sad"
           pest.petimage = "http://i0.kym-cdn.com/photos/images/original/000/945/016/648.png"
      }
      else
      {
          pest.petmood = "Dead"
      }

      document.getElementById("state").value = pest.state
      document.getElementById("pepe").value = pest.pepe
      document.getElementById("petimage").src = pest.petimage
      document.getElementById("counter").value = pest.counter
}
function Simulate(pest)
{

 pest.counter++
 var state = pest.state

      var n = Math.random(pest.state)

      if( state == "Happy" && n < 0.5 )
          pest.state = "Hungry"
      else if( state == "Hungry" && n < 0.4 )
          pest.state = "Angry"
      else if( state == "Angry" && n < 0.42 )
          pest.state = "Sad"
      else if( state == "Sad" && n < 0.43 )
          pest.state = "Sleepy"
      else if( state == "Sleepy" && n < 0.3 )
          pest.state = "Dead"

      display(thePest)
      setTimeout("Simulate(thePest)",1000)
}
function Feed(pest)
{

 var state = pest.state

  if( state == "Hungry" )
          pest.state = "Happy"

         display(thePest)
}
function Love(pest)
{

 var state = pest.state

  if( state == "Sad" )
          pest.state = "Happy"

         display(thePest)
}
function Mad(pest)
{

 var state = pest.state

  if( state == "Mad" )
          pest.state = "Happy"

         display(thePest)
}
function Annoy(pest)
{

 var state = pest.state

  if( state == "Happy" )
          pest.state = "Angry"

         display(thePest)
}
</script>`

Body:
The only problem i see is that you do not ever call the startup which fires up the whole process.

Update without using current state for randomness

var thePest

function pestConstructor(state, pepe, petimage, counter) {

  this.state = state
  this.pepe = pepe
  this.petimage = petimage
  this.counter = counter
}

function startup() {

  thePest = new pestConstructor("Happy", "Hi!",
    "https://ih1.redbubble.net/image.141976807.7205/flat,800x800,075,t.jpg", 0)

  display(thePest)
  setTimeout("Simulate(thePest)", 1000)
}

function display(pest) {

  var state = pest.state

  if (state == "Angry") {
    pest.pepe = "AHHHH!!!"
    pest.petimage = "http://i0.kym-cdn.com/entries/icons/original/000/017/318/angry_pepe.jpg"
  } else if (state == "Happy") {
    pest.pepe = "Hi!"
    pest.petimage = "https://ih1.redbubble.net/image.141976807.7205/flat,800x800,075,t.jpg"
  } else if (state == "Hungry") {
    pest.pepe = "FOOD!"
    pest.petimage = "https://pbs.twimg.com/media/CS5XSd1UkAEfpUv.png"
  } else if (state == "Sad") {
    pest.pepe = "I'm Sad"
    pest.petimage = "http://i0.kym-cdn.com/photos/images/original/000/945/016/648.png"
  } else {
    pest.petmood = "Dead"
  }

  document.getElementById("state").value = pest.state
  document.getElementById("pepe").value = pest.pepe
  document.getElementById("petimage").src = pest.petimage
  document.getElementById("counter").value = pest.counter
}

function Simulate(pest) {

  pest.counter++
    var state = pest.state

  var n = Math.random(pest.state)
  // assuming you want to stop when Dead
  if (pest.state !== "Dead") {
    if (state == "Sleepy" && n < 0.1)
      pest.state = "Dead"
    else if (n < 0.2)
      pest.state = "Hungry"
    else if (n < 0.3)
      pest.state = "Angry"
    else if (n < 0.4)
      pest.state = "Sad"
    else if (n < 0.5)
      pest.state = "Sleepy"

    display(thePest)
    setTimeout("Simulate(thePest)", 1000)
  }
}

function Feed(pest) {

  var state = pest.state

  if (state == "Hungry")
    pest.state = "Happy"

  display(thePest)
}

function Love(pest) {

  var state = pest.state

  if (state == "Sad")
    pest.state = "Happy"

  display(thePest)
}

function Mad(pest) {

  var state = pest.state

  if (state == "Mad")
    pest.state = "Happy"

  display(thePest)
}

function Annoy(pest) {

  var state = pest.state

  if (state == "Happy")
    pest.state = "Angry"

  display(thePest)
}

startup();

state: <input id="state"><br> pepe: <input id="pepe"><br> img: <img src="" id="petimage"><br> counter: <input id="counter"><br>

Just a heads up: You have no display data for the Sleepy state.


问:
How can I add an audioclip in Javafx?
I'm trying to add a sound once a button is clicked and it doesn't seem to be working. I've been trying different approaches and this seems to be the closest thing to work except for this one error message. I'm open to any suggestions.</p>

```<code>package beatbox;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.GridPane;
import javafx.scene.media.AudioClip;
import javafx.stage.Stage;
import sun.audio.AudioPlayer;

 public class BeatBox extends Application {
 // Adding audio clip
 private static final AudioClip clip1 = new AudioClip(AudioPlayer.class.getResource("http://www.wavlist.com/soundfx/029/piano2.wav").toString());

@Override
public void start(Stage primaryStage) {

    // Create gridpane for button display
    GridPane gridPane = new GridPane();
    Button btn1 = new Button("");
    gridPane.add(btn1, 0, 0, 1, 1);

    // Playing sound and changing color on button click
    btn1.setOnAction(new EventHandler<ActionEvent>() {

        @Override
        public void handle(ActionEvent event) {
            clip1.play();
            btn1.setStyle(" -fx-base: #99ccff;");
        }
    });

    Scene scene = new Scene(gridPane, 302, 335);
    primaryStage.setScene(scene);
    primaryStage.setResizable(false);
    primaryStage.show();
    }
    public static void main(String[] args) {
    launch(args);
}
</code>```

<p>(UPDATE)
here's the exception </p>

```<code>Exception in thread "JavaFX Application Thread" Exception in thread "main" java.lang.ExceptionInInitializerError
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplicationWithArgs$156(LauncherImpl.java:352)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$175(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NullPointerException
at beatbox.BeatBox.<clinit>(BeatBox.java:24)
</code>```

答:
OK, first, please close the main method with curly brace "}" to get rid of syntax error. Second, remove the import:

```<code>import sun.audio.AudioPlayer;
</code>```

and import this:

```<code>import javafx.scene.media.AudioClip;
</code>```

Third, remove the AudioPlayer.class.getResource().toString and just use the url.

```<code>private static final AudioClip clip1 = new AudioClip("http://www.wavlist.com/soundfx/029/piano2.wav");
</code>```

That's it. Audio plays!

Title: How can I add an audioclip in Javafx?

Body:
I'm trying to add a sound once a button is clicked and it doesn't seem to be working. I've been trying different approaches and this seems to be the closest thing to work except for this one error message. I'm open to any suggestions.

package beatbox;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.GridPane;
import javafx.scene.media.AudioClip;
import javafx.stage.Stage;
import sun.audio.AudioPlayer;

 public class BeatBox extends Application {
 // Adding audio clip
 private static final AudioClip clip1 = new AudioClip(AudioPlayer.class.getResource("http://www.wavlist.com/soundfx/029/piano2.wav").toString());

@Override
public void start(Stage primaryStage) {

    // Create gridpane for button display
    GridPane gridPane = new GridPane();
    Button btn1 = new Button("");
    gridPane.add(btn1, 0, 0, 1, 1);

    // Playing sound and changing color on button click
    btn1.setOnAction(new EventHandler<ActionEvent>() {

        @Override
        public void handle(ActionEvent event) {
            clip1.play();
            btn1.setStyle(" -fx-base: #99ccff;");
        }
    });

    Scene scene = new Scene(gridPane, 302, 335);
    primaryStage.setScene(scene);
    primaryStage.setResizable(false);
    primaryStage.show();
    }
    public static void main(String[] args) {
    launch(args);
}

(UPDATE)
here's the exception

Exception in thread "JavaFX Application Thread" Exception in thread "main" java.lang.ExceptionInInitializerError
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplicationWithArgs$156(LauncherImpl.java:352)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$175(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NullPointerException
at beatbox.BeatBox.<clinit>(BeatBox.java:24)

Body:
OK, first, please close the main method with curly brace "}" to get rid of syntax error. Second, remove the import:

import sun.audio.AudioPlayer;

and import this:

import javafx.scene.media.AudioClip;

Third, remove the AudioPlayer.class.getResource().toString and just use the url.

private static final AudioClip clip1 = new AudioClip("http://www.wavlist.com/soundfx/029/piano2.wav");

That's it. Audio plays!


问:
Angular-cli project cross platform build issue
I've created experimental angular-cli project on Mac. Than I've moved it onto ubuntu and cant build:

```<code>$ npm install
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@^1.0.0 (node_modules/chokidar/node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.1.3: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})
</code>```

& start one:

```<code>$ ng serve
Cannot read property 'config' of null
TypeError: Cannot read property 'config' of null
    at Class.run (/project-path/node_modules/@angular/cli/tasks/serve.js:51:63)
    at check_port_1.checkPort.then.port (/project-path/node_modules/@angular/cli/commands/serve.js:123:26)
    at process._tickCallback (internal/process/next_tick.js:103:7)
</code>```

I confused, because it worked perfectly on Mac.

Env details

```<code>$ npm -v
4.0.5
$ node -v
v7.4.0
$ ng -v
Angular CLI: 1.5.5
Node: 7.4.0
OS: linux x64
Angular: 5.0.5
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, router

@angular/cdk: 5.0.0-rc0
@angular/cli: 1.5.5
@angular/material: 5.0.0-rc0
@angular-devkit/build-optimizer: 0.0.34
@angular-devkit/core: 0.0.22
@angular-devkit/schematics: 0.0.39
@ngtools/json-schema: 1.1.0
@ngtools/webpack: 1.8.5
@schematics/angular: 0.1.9
typescript: 2.4.2
webpack: 3.8.1
</code>```

I've found also answer npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.0.14 it partly describes the messages, but it doesn't help me with my project running. (It can't be started any way).

答:
To make my project runnable on Ubuntu I need a missed file on Mac (it seems mac does not need one) - .angular-cli.json:

```<code>{
  "name": "angular4-in60-minutes",
  "version": "0.0.0",
  "license": "MIT",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "^5.0.1",
    "@angular/cdk": "^5.0.0-rc0",
    "@angular/common": "^5.0.0",
    "@angular/compiler": "^5.0.0",
    "@angular/core": "^5.0.0",
    "@angular/forms": "^5.0.0",
    "@angular/http": "^5.0.0",
    "@angular/material": "^5.0.0-rc0",
    "@angular/platform-browser": "^5.0.0",
    "@angular/platform-browser-dynamic": "^5.0.0",
    "@angular/router": "^5.0.0",
    "bootstrap": "^3.2.1",
    "core-js": "^2.4.1",
    "hammerjs": "^2.0.8",
    "jquery": "^3.2.1",
    "popper.js": "^1.12.9",
    "rxjs": "^5.5.2",
    "zone.js": "^0.8.14"
  },
  "devDependencies": {
    "@angular/cli": "^1.5.0",
    "@angular/compiler-cli": "^5.0.0",
    "@angular/language-service": "^5.0.0",
    "@types/jasmine": "~2.5.53",
    "@types/jasminewd2": "~2.0.2",
    "@types/node": "~6.0.60",
    "codelyzer": "^4.0.1",
    "jasmine-core": "~2.6.2",
    "jasmine-spec-reporter": "~4.1.0",
    "karma": "~1.7.0",
    "karma-chrome-launcher": "~2.1.1",
    "karma-cli": "~1.0.1",
    "karma-coverage-istanbul-reporter": "^1.2.1",
    "karma-jasmine": "~1.1.0",
    "karma-jasmine-html-reporter": "^0.2.2",
    "protractor": "~5.1.2",
    "ts-node": "~3.2.0",
    "tslint": "~5.7.0",
    "typescript": "~2.4.2"
  }
}
</code>```

After adding this file my project can be started correctly. But issue with warnings present anyway

```<code>npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@^1.0.0 (node_modules/chokidar/node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.1.3: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})
</code>```

Body:
I've created experimental angular-cli project on Mac. Than I've moved it onto ubuntu and cant build:

$ npm install
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@^1.0.0 (node_modules/chokidar/node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.1.3: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})

& start one:

$ ng serve
Cannot read property 'config' of null
TypeError: Cannot read property 'config' of null
    at Class.run (/project-path/node_modules/@angular/cli/tasks/serve.js:51:63)
    at check_port_1.checkPort.then.port (/project-path/node_modules/@angular/cli/commands/serve.js:123:26)
    at process._tickCallback (internal/process/next_tick.js:103:7)

I confused, because it worked perfectly on Mac.

Env details

$ npm -v
4.0.5
$ node -v
v7.4.0
$ ng -v
Angular CLI: 1.5.5
Node: 7.4.0
OS: linux x64
Angular: 5.0.5
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, router

@angular/cdk: 5.0.0-rc0
@angular/cli: 1.5.5
@angular/material: 5.0.0-rc0
@angular-devkit/build-optimizer: 0.0.34
@angular-devkit/core: 0.0.22
@angular-devkit/schematics: 0.0.39
@ngtools/json-schema: 1.1.0
@ngtools/webpack: 1.8.5
@schematics/angular: 0.1.9
typescript: 2.4.2
webpack: 3.8.1

I've found also answer npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.0.14 it partly describes the messages, but it doesn't help me with my project running. (It can't be started any way).

Body:
To make my project runnable on Ubuntu I need a missed file on Mac (it seems mac does not need one) - .angular-cli.json:

{
  "name": "angular4-in60-minutes",
  "version": "0.0.0",
  "license": "MIT",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "^5.0.1",
    "@angular/cdk": "^5.0.0-rc0",
    "@angular/common": "^5.0.0",
    "@angular/compiler": "^5.0.0",
    "@angular/core": "^5.0.0",
    "@angular/forms": "^5.0.0",
    "@angular/http": "^5.0.0",
    "@angular/material": "^5.0.0-rc0",
    "@angular/platform-browser": "^5.0.0",
    "@angular/platform-browser-dynamic": "^5.0.0",
    "@angular/router": "^5.0.0",
    "bootstrap": "^3.2.1",
    "core-js": "^2.4.1",
    "hammerjs": "^2.0.8",
    "jquery": "^3.2.1",
    "popper.js": "^1.12.9",
    "rxjs": "^5.5.2",
    "zone.js": "^0.8.14"
  },
  "devDependencies": {
    "@angular/cli": "^1.5.0",
    "@angular/compiler-cli": "^5.0.0",
    "@angular/language-service": "^5.0.0",
    "@types/jasmine": "~2.5.53",
    "@types/jasminewd2": "~2.0.2",
    "@types/node": "~6.0.60",
    "codelyzer": "^4.0.1",
    "jasmine-core": "~2.6.2",
    "jasmine-spec-reporter": "~4.1.0",
    "karma": "~1.7.0",
    "karma-chrome-launcher": "~2.1.1",
    "karma-cli": "~1.0.1",
    "karma-coverage-istanbul-reporter": "^1.2.1",
    "karma-jasmine": "~1.1.0",
    "karma-jasmine-html-reporter": "^0.2.2",
    "protractor": "~5.1.2",
    "ts-node": "~3.2.0",
    "tslint": "~5.7.0",
    "typescript": "~2.4.2"
  }
}

After adding this file my project can be started correctly. But issue with warnings present anyway

npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@^1.0.0 (node_modules/chokidar/node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.1.3: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})


问:
JavaFX from RHEL
Previously I am developing applications with JavaFX in Oracle Java SE shipped by Red Hat but it seems it is no longer offered as in https://access.redhat.com/articles/3253281. However, it seems that the OpenJDK coming from rhel-7-server-rpms repository does not come with JavaFX.

Are there better ways instead of just installing packages from outside the repositories provided by Red Hat? I don't want to test each environment with self-compiled OpenJFX binary one by one.

答:
Oracle provide RPMs you can download:

http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html

Those RPMs are not in a YUM repository that you could just point your red hat boxes to.

You can download the RPMs and create your own rum repository, then add your custom repository to the yum repository list for each of your target machines and after that use yum to install the rpms to your boxes.  You would need to restrict this so that it isn't fully open to the public I think (to meet Oracle Java distribution requirements).

If you built your own version of the Java SE which included JavaFX from OpenJFX sources (or you can find a package for your target OS which somebody else has built), then you could host that in an unrestricted manner in your own repository (or any other public repository out there), or pull the package from a public repository if somebody else has already put it there.

If you don't need a repository, and can just scp the rpms to the relevant machines then you can directly install the rpms on the machines without setting up your own custom repository.

If you package your application as a self-contained application, then the application install bundle itself will include the JRE, so you don't need to worry about installing that separately on the machine (and also don't potentially run into situations where the user has installed a runtime version which is not compatible or tested with your code).  Perhaps that is a preferred path for you.

I don't know RedHat's policy for OpenJDK releases and builds to their repositories.  It would be nice if they included JavaFX in their OpenJDK distributions in their repositories or provided a separate package for OpenJFX, similar to what Ubuntu do.  Perhaps they might include JavaFX in their OpenJDK 9 distributions.  They have info on RHEL Support for OpenJDK 9, so maybe they say something there (I can't read it as I am not a RHEL subscriber).  If you have a support contract with Redhat and the info isn't available on their site, then you could ping them and ask them about OpenJFX JavaFX distributions hosted in their repository (to see if they are there or not or if they have a plan to put them there).

Title: JavaFX from RHEL


问:
Rails how to find records where the has_many relation exists?
In the below association, I want to collect all Users who don't have any projects->

```<code>class User <  ActiveRecord::Base
  has_many :projects, :foreign_key => :user_id
end

class Projects < ActiveRecord::Base
  belongs_to :user, :foreign_key => "user_id"
end
</code>```

From User model, how can I get all the users that do not have any projects? I tried using includes and join but didn't get the expected result

答:
You could try:

```<code>User.where.not(id: Project.pluck(:user_id).uniq)
</code>```

Breaking it down:

```<code>Project.pluck(:user_id).uniq
</code>```

will give you an array of user_ids from your projects. Essentially, users with projects.

Then:

```<code>User.where.not(id: Project.pluck(:user_id).uniq)
</code>```

returns users who have an id that is not in the array of users with projects.

Body:
In the below association, I want to collect all Users who don't have any projects->

class User <  ActiveRecord::Base
  has_many :projects, :foreign_key => :user_id
end

class Projects < ActiveRecord::Base
  belongs_to :user, :foreign_key => "user_id"
end

From User model, how can I get all the users that do not have any projects? I tried using includes and join but didn't get the expected result

Body:
You could try:

User.where.not(id: Project.pluck(:user_id).uniq)

Breaking it down:

Project.pluck(:user_id).uniq

will give you an array of user_ids from your projects. Essentially, users with projects.

Then:

User.where.not(id: Project.pluck(:user_id).uniq)

returns users who have an id that is not in the array of users with projects.


问:
Is it possible to specify `panic = "abort"` for a specific target?
If I specify panic like this, it works for all targets:

```<code>[profile.release]
panic = "abort"
</code>```

I want to specify panic = "abort" only for target=arm-linux-androideabi.

答:
You will need to add a .cargo/config to your project and use it to specify the panic settings instead of Cargo.toml:

```<code>[target.arm-linux-androideabi]
rustflags = ["-C", "panic=abort"]
</code>```

The two main configuration headings you will want to look at are [target.$triple] and [target.'cfg(...)'].

Body:
If I specify panic like this, it works for all targets:

[profile.release]
panic = "abort"

I want to specify panic = "abort" only for target=arm-linux-androideabi.

Body:
You will need to add a .cargo/config to your project and use it to specify the panic settings instead of Cargo.toml:

[target.arm-linux-androideabi]
rustflags = ["-C", "panic=abort"]

The two main configuration headings you will want to look at are [target.$triple] and [target.'cfg(...)'].

ContentLicense: CC BY-SA 4.0


问:
Foreach Through QJsonObject to get Key/Value Pair
I am wondering how I would foreach through a QJsonObject to get the key/value pairs in C++? So far, I am only able to get the value.

```<code>//main.cpp
QFile file(":/geoip.json");
file.open(QIODevice::ReadOnly);
QByteArray rawData = file.readAll();
file.close();
QJsonDocument doc(QJsonDocument::fromJson(rawData));
QJsonObject json = doc.object();
foreach(const QJsonValue &value, json) {
    QJsonObject obj = value.toObject();
    qDebug() << value;
}

//geoip.json
{
    "Afghanistan": "58.147.159.255",
    "Albania": "31.22.63.255",
    "Algeria": "105.235.143.255",
    "American Samoa": "202.70.115.241",
    "Andorra": "109.111.127.255",
    "Angola": "105.175.255.255",
    "Anguilla": "208.66.50.44",
    "Antarctica": "46.36.195.10"
}
</code>```

答:
John already gave the answer. Using keys() a complete working solution would be:</p>

```<code>#include <QCoreApplication>
#include <QFile>
#include <QByteArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonValue>
#include <QDebug>

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

    //main.cpp
    QFile file("path/to/geoip.json");
    file.open(QIODevice::ReadOnly);
    QByteArray rawData = file.readAll();
    file.close();
    QJsonDocument doc(QJsonDocument::fromJson(rawData));
    QJsonObject json = doc.object();
    foreach(const QString& key, json.keys()) {
        QJsonValue value = json.value(key);
        qDebug() << "Key = " << key << ", Value = " << value.toString();
    }

    return a.exec();
}
</code>```

Body:
I am wondering how I would foreach through a QJsonObject to get the key/value pairs in C++? So far, I am only able to get the value.

//main.cpp
QFile file(":/geoip.json");
file.open(QIODevice::ReadOnly);
QByteArray rawData = file.readAll();
file.close();
QJsonDocument doc(QJsonDocument::fromJson(rawData));
QJsonObject json = doc.object();
foreach(const QJsonValue &value, json) {
    QJsonObject obj = value.toObject();
    qDebug() << value;
}

//geoip.json
{
    "Afghanistan": "58.147.159.255",
    "Albania": "31.22.63.255",
    "Algeria": "105.235.143.255",
    "American Samoa": "202.70.115.241",
    "Andorra": "109.111.127.255",
    "Angola": "105.175.255.255",
    "Anguilla": "208.66.50.44",
    "Antarctica": "46.36.195.10"
}

Body:
John already gave the answer. Using keys() a complete working solution would be:

#include <QCoreApplication>
#include <QFile>
#include <QByteArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonValue>
#include <QDebug>

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

    //main.cpp
    QFile file("path/to/geoip.json");
    file.open(QIODevice::ReadOnly);
    QByteArray rawData = file.readAll();
    file.close();
    QJsonDocument doc(QJsonDocument::fromJson(rawData));
    QJsonObject json = doc.object();
    foreach(const QString& key, json.keys()) {
        QJsonValue value = json.value(key);
        qDebug() << "Key = " << key << ", Value = " << value.toString();
    }

    return a.exec();
}


问:
Don't know where to start with selecting a row in php
Ok guys I know this might not be the correct way to ask a question but I have looked as far as I could go. I am a bit stuck on how to go about this problem, probably why I can't find a solution to it. I have a form that the info gets inserted to a db, then you are able to view the info from the database on another page that list everything inserted. My question is how would I go about selecting a row from the table that displays all the info from a row on the db and redirect to another page to edit it? I want to redirect to another page to view/edit all the info.

What I think would work is in the table that shows the info I could put a radio box and have a button at the top to click to edit that row. I don't really know how to assign that radio button to the actual row however.

Here is my table:

```<code><?php
                $sql = "SELECT * FROM employees ORDER BY LastName";
                $result = $mysqli -> query($sql);

                if ($result->num_rows > 0) {
                    echo "
                    <table class='table table-hover table-responsive'>
                        <thead class='thead-dark'>
                            <tr>
                                <th class='table-primary' scope='col'>#</th>
                                <th class='table-primary' scope='col'>First Name</th>
                                <th class='table-primary' scope='col-1'>M.I.</th>
                                <th class='table-primary' scope='col'>Last Name</th>
                                <th class='table-primary' scope='col'>Phone</th>
                                <th class='table-primary' scope='col'>Address</th>
                                <th class='table-primary' scope='col'>Email</th>
                                <th class='table-primary' scope='col'>Birth Date</th>
                                <th class='table-primary' scope='col'>EID</th>
                                <th class='table-primary' scope='col'>Gender</th>
                                <th class='table-primary' scope='col'>Ethnicity</th>
                                <th class='table-primary' scope='col'>Status</th>
                                <th class='table-primary' scope='col'>Hours</th>
                                <th class='table-primary' scope='col'>EAP Access</th>
                            </tr>
                          </thead>";
                    // output data of each row
                    while ($row = $result->fetch_assoc()) {
                        echo "
                        <tbody>
                            <tr class='table-dark'>
                                <td>" . $row['UserID']. "</td>
                              <td>" . $row['FirstName']. "</td>
                              <td>" . $row['Middle']. "</td>
                              <td>" . $row['LastName']. "</td>
                                <td>" . $row['PrimaryPhone']. "</td>
                                <td>" . $row['Address'] . $row['City'] . $row['State'] . $row['Zipcode']. "</td>
                                <td>" . $row['Email']. "</td>
                                <td>" . $row['DateOfBirth']. "</td>
                                <td>" . $row['EID']. "</td>
                                <td>" . $row['Gender']. "</td>
                                <td>" . $row['Ethnicity']." </td>
                                <td>" . $row['Status']. "</td>
                                <td>" . $row['Hours']. "</td>
                                <td>" . $row['eapAccess']. "</td>
                            </tr>
                        </tbody>";
                    }
                    echo "</table>";
                } else {
                    echo "0 results";
                }
            ?>
</code>```

If I added a <input type="radio" name="selected"> before the userID column like and had a button to select that row, how would I be able to have that row display on a seperate page?

I am still new to php, but this is beyond me and can't find anything remotely close to an answer.

答:
Your  as well as all other information you what to send to another script should be wrapped inside  .
Set the form action, i.e the script path, and use either POST or GET method( I prefer POST).
On your next script, you will probably use isset() to check if the userID was received, then you can Carry on from there.</p>

Body:
Ok guys I know this might not be the correct way to ask a question but I have looked as far as I could go. I am a bit stuck on how to go about this problem, probably why I can't find a solution to it. I have a form that the info gets inserted to a db, then you are able to view the info from the database on another page that list everything inserted. My question is how would I go about selecting a row from the table that displays all the info from a row on the db and redirect to another page to edit it? I want to redirect to another page to view/edit all the info.

What I think would work is in the table that shows the info I could put a radio box and have a button at the top to click to edit that row. I don't really know how to assign that radio button to the actual row however.

Here is my table:

<?php
                $sql = "SELECT * FROM employees ORDER BY LastName";
                $result = $mysqli -> query($sql);

                if ($result->num_rows > 0) {
                    echo "

                                #
                                First Name
                                M.I.
                                Last Name
                                Phone
                                Address
                                Email
                                Birth Date
                                EID
                                Gender
                                Ethnicity
                                Status
                                Hours
                                EAP Access

";
                    // output data of each row
                    while ($row = $result->fetch_assoc()) {
                        echo "

                                " . $row['UserID']. "
                              " . $row['FirstName']. "
                              " . $row['Middle']. "
                              " . $row['LastName']. "
                                " . $row['PrimaryPhone']. "
                                " . $row['Address'] . $row['City'] . $row['State'] . $row['Zipcode']. "
                                " . $row['Email']. "
                                " . $row['DateOfBirth']. "
                                " . $row['EID']. "
                                " . $row['Gender']. "
                                " . $row['Ethnicity']."
                                " . $row['Status']. "
                                " . $row['Hours']. "
                                " . $row['eapAccess']. "

";
                    }
                    echo "
";
                } else {
                    echo "0 results";
                }
            ?>

If I added a <input type="radio" name="selected"> before the userID column like and had a button to select that row, how would I be able to have that row display on a seperate page?

I am still new to php, but this is beyond me and can't find anything remotely close to an answer.


问:
Selected property on SelectListItem not being set by SelectList constructor
I'm creating a SelectList to pass to a Html.DropDownList, but the correct value doesn't seem to be populating

```<code>var x = new SelectList(new[] {
    new SelectListItem() { Value="1", Text="Vanilla"},
    new SelectListItem() { Value="2", Text="Chocolate"},
    new SelectListItem() { Value="3", Text="Strawberry"}
}, "Value", "Text", "2");
</code>```

SelectList should take a constructor that takes in the selectedValue:

```<code>public SelectList(
    IEnumerable items,
    string dataValueField,
    string dataTextField,
    object selectedValue
)
</code>```

But this only sets the SelectedValue on the entire collection.  The individual SelectListItems haven't been set as Selected

Do I need to iterate over them individually and set selected for each as in this question?

答:
The Selected property is being set by the SelectList constructor. The image you have shown is for the items argument (i.e the collection of SelectListItem that you passing to the method), not the result of calling the method.

The constructor does not modify the collection passed to it, it creates a new IEnumerable<SelectListItem>, and if you inspect the value of var x, then you will see that the 2nd SelectListItem (the one with Value = "2") will have its Selected property set to true.

However, the purpose of the SelectListItem class is for use in one of the HtmlHelper methods that generates a <select> (DropDownList(), DropDownListFor(), ListBox() and ListBoxFor() methods) which accept an IEnumerable<SelectListItem> as either the 1st or 2nd argument.

Unless you specifically not binding to a model property (e.g. @Html.DropDownList("NotAModelProperty", Model.YourSelectList)), then setting the Selected property is ignored because the method sets the selected option based on the value of the property your binding to (refer How to set “selectedValue” in DropDownListFor Html helper for more detail), therefore creating a new IEnumerable<SelectListItem> from the first one by using new SelectList(...) is pointless extra overhead.

The reason for using the SelectList constructor is to create an IEnumerable<SelectListItem> from an existing collection of objects, for example

```<code>IEnumerable<SelectListItem> options = new SelectList(db.Flavors, "ID", "Name")
</code>```

which would get the records from the Flavors table, and set the Value based on its ID property, and the Text based on its Name property. It just provides an alternative to using (say)

```<code>IEnumerable<SelectListItem> options = db.Flavors.Select(x => new SelectListItem
{
    Value = x.ID.ToString(),
    Text = x.Name
});
</code>```

Body:
I'm creating a SelectList to pass to a Html.DropDownList, but the correct value doesn't seem to be populating

var x = new SelectList(new[] {
    new SelectListItem() { Value="1", Text="Vanilla"},
    new SelectListItem() { Value="2", Text="Chocolate"},
    new SelectListItem() { Value="3", Text="Strawberry"}
}, "Value", "Text", "2");

SelectList should take a constructor that takes in the selectedValue:

public SelectList(
    IEnumerable items,
    string dataValueField,
    string dataTextField,
    object selectedValue
)

But this only sets the SelectedValue on the entire collection.  The individual SelectListItems haven't been set as Selected

Do I need to iterate over them individually and set selected for each as in this question?

Body:
The Selected property is being set by the SelectList constructor. The image you have shown is for the items argument (i.e the collection of SelectListItem that you passing to the method), not the result of calling the method.

The constructor does not modify the collection passed to it, it creates a new IEnumerable<SelectListItem>, and if you inspect the value of var x, then you will see that the 2nd SelectListItem (the one with Value = "2") will have its Selected property set to true.

However, the purpose of the SelectListItem class is for use in one of the HtmlHelper methods that generates a <select> (DropDownList(), DropDownListFor(), ListBox() and ListBoxFor() methods) which accept an IEnumerable<SelectListItem> as either the 1st or 2nd argument.

Unless you specifically not binding to a model property (e.g. @Html.DropDownList("NotAModelProperty", Model.YourSelectList)), then setting the Selected property is ignored because the method sets the selected option based on the value of the property your binding to (refer How to set “selectedValue” in DropDownListFor Html helper for more detail), therefore creating a new IEnumerable<SelectListItem> from the first one by using new SelectList(...) is pointless extra overhead.

The reason for using the SelectList constructor is to create an IEnumerable<SelectListItem> from an existing collection of objects, for example

IEnumerable<SelectListItem> options = new SelectList(db.Flavors, "ID", "Name")

which would get the records from the Flavors table, and set the Value based on its ID property, and the Text based on its Name property. It just provides an alternative to using (say)

IEnumerable<SelectListItem> options = db.Flavors.Select(x => new SelectListItem
{
    Value = x.ID.ToString(),
    Text = x.Name
});


问:
How to display body and headers before sending POST request?
I use a library requests:

```<code>import requests

r = requests.post(url=url, data=data, headers=headers, auth=(self.api_key, ''))
</code>```

How to display body and headers before sending POST request? or display full request how it is sent?

Because server returns 400 HTTP with message Bad Request. So I need to see what is sending.

When I do:

```<code>print r.request.body
</code>```

It returns:

```<code>subcategory_id=1378&category_id=45&features=id&features=value&features=id&features=value&features=id&features=value&offer_type=18979
</code>```

But body is:

```<code>data = {
            'category_id': category_id,
            'subcategory_id': subcategory_id,
            'offer_type': offer_type,
            'features': [
                {"id": "7", "value": "12900"},
                {"id": "12", "value": "Title adadadadasdasdadad"},
                {"id": "16", "value": ["3360383821"]}
          ]
        }
</code>```

How is it possible?

答:
r.request is the corresponding Request object you need.

```<code>import requests

r = requests.post(url=url, data=data, headers=headers, auth=(self.api_key, ''))
print r.request.headers
print r.request.body
</code>```

You can do it after you get the response, everything will still be there. See PreparedRequest.

As for your edited question, use requests.post(url=url, json=data, ...).

Body:
I use a library requests:

import requests

r = requests.post(url=url, data=data, headers=headers, auth=(self.api_key, ''))

How to display body and headers before sending POST request? or display full request how it is sent?

Because server returns 400 HTTP with message Bad Request. So I need to see what is sending.

When I do:

print r.request.body

It returns:

subcategory_id=1378&category_id=45&features=id&features=value&features=id&features=value&features=id&features=value&offer_type=18979

But body is:

data = {
            'category_id': category_id,
            'subcategory_id': subcategory_id,
            'offer_type': offer_type,
            'features': [
                {"id": "7", "value": "12900"},
                {"id": "12", "value": "Title adadadadasdasdadad"},
                {"id": "16", "value": ["3360383821"]}
          ]
        }

How is it possible?

Body:
r.request is the corresponding Request object you need.

import requests

r = requests.post(url=url, data=data, headers=headers, auth=(self.api_key, ''))
print r.request.headers
print r.request.body

You can do it after you get the response, everything will still be there. See PreparedRequest.

As for your edited question, use requests.post(url=url, json=data, ...).


问:
DOMNodeInserted or hashchange
I am trying to write a JavaScript script that is "overlayed" on top of a Facebook page. It uses DOMContentLoaded to detect when content is loaded, then adds some extra stuff in. However, because Facebook doesn't actually "reload" the page when going to a new page (it just uses AJAX), the DOMContentLoaded handler doesn't run again, even though there is new stuff to look through.

Anyway, to detect the change, I thought about using onhashchange since Facebook used to change the page's hash, but in Firefox 4 (I need to support Firefox 3 and later with this, but no other browsers), Facebook doesn't change the hash anymore and in pre-Firefox 3.6 there is no onhashchange.

I thought about using DOMNodeInserted, but would that really slow down the page? (I really can't have any slowdowns in this script.)

答:
you might want to monitor the windows.history object, see the following answer, on how facebook uses it to update pages:
"Redirect" page without refresh (Facebook photos style)</p>

ContentLicense: CC BY-SA 2.5

Title: DOMNodeInserted or hashchange


问:
Kafka Streams mapping KTable value into separate values
I have a Kafka Stream App that reads a single topic as a KTable, transforms each element into 0-n elements and writes all of them to another topic. The flow looks like this (simplified by quite a bit):

```<code>('a', '123') -> ('a', '1,2,3') -> ('a1', '1'), ('a2', '2'), ('a3', '3')
</code>```

Is this doable using Kafka Stream DSL? All topics in use are compact, therefore I want to simulate a table and never get rid of old values.

tl;dr; how to transform a message into multiple messages?

答:
Not sure if you can express this with the DSL. But it's rather simple to do this with Processor API:

builder.stream("input-topic").transform(...).to("output-topic");
```

You attach a key-value store to your transform() and do the following for each input record:

check if there is a corresponding key-value pair in the store

if yes (ie, store.get()!=null), take the old value from the store and split it; replace the value for each "split record" with null and emit all those records

if input record value!=null, put the input record as-is to the store and split the input record and emit the individual output records

if input record value==null, delete key from the store

Check out the docs for more details: https://docs.confluent.io/current/streams/developer-guide/dsl-api.html#applying-processors-and-transformers-processor-api-integration

Body:
I have a Kafka Stream App that reads a single topic as a KTable, transforms each element into 0-n elements and writes all of them to another topic. The flow looks like this (simplified by quite a bit):

('a', '123') -> ('a', '1,2,3') -> ('a1', '1'), ('a2', '2'), ('a3', '3')

Is this doable using Kafka Stream DSL? All topics in use are compact, therefore I want to simulate a table and never get rid of old values.

tl;dr; how to transform a message into multiple messages?

Body:
Not sure if you can express this with the DSL. But it's rather simple to do this with Processor API:

builder.stream("input-topic").transform(...).to("output-topic");

You attach a key-value store to your transform() and do the following for each input record:

check if there is a corresponding key-value pair in the store

if yes (ie, store.get()!=null), take the old value from the store and split it; replace the value for each "split record" with null and emit all those records

if input record value!=null, put the input record as-is to the store and split the input record and emit the individual output records

if input record value==null, delete key from the store

Check out the docs for more details: https://docs.confluent.io/current/streams/developer-guide/dsl-api.html#applying-processors-and-transformers-processor-api-integration


问:
CircleCI CLI looks in wrong path for Android SDK
I'm using the CircleCI CLI to test running my unit tests locally. Every time I run I get:

```<code>FAILURE: Build failed with an exception.

* What went wrong:
A problem occurred configuring project ':appName'.
> The SDK directory '/Users/me/workspace/android-sdk-macosx' does not exist.
</code>```

If I add in a command to run echo $ANDROID_HOME it correctly points to /opt/android/sdk I can't figure out why it's getting my local $ANDROID_HOME value and not what's configured in the container.

What am I missing?

答:
After an hour of chasing my tail here's the problem. Because I'm running the CircleCI CLI locally it's not pulling all the code fresh from github, it's just copying my local file system, and my local file system has local.properties which points to my local android SDK home path. So I added this to my config.yml and it all works

```<code>steps:
      - run:
          name: remove local settings
          command: rm local.properties
</code>```

Body:
I'm using the CircleCI CLI to test running my unit tests locally. Every time I run I get:

FAILURE: Build failed with an exception.

* What went wrong:
A problem occurred configuring project ':appName'.
> The SDK directory '/Users/me/workspace/android-sdk-macosx' does not exist.

If I add in a command to run echo $ANDROID_HOME it correctly points to /opt/android/sdk I can't figure out why it's getting my local $ANDROID_HOME value and not what's configured in the container.

What am I missing?

Body:
After an hour of chasing my tail here's the problem. Because I'm running the CircleCI CLI locally it's not pulling all the code fresh from github, it's just copying my local file system, and my local file system has local.properties which points to my local android SDK home path. So I added this to my config.yml and it all works

steps:
      - run:
          name: remove local settings
          command: rm local.properties


问:
Zend framework findManyToManyRowset with condition on 3rd column
Is there a way I can do a condition on the join table with a many to many in ZF ?

For example I have table A | A_B |B

And B has columns A_ID | B_ID | PUBLISHED

```<code>$model = new Model_DbTable_A();
$select = $model->select()->where('id = ?', $id);
$row = $model->fetchRow($select);
$b = $row->findManyToManyRowset('Model_DbTable_B', 'Model_DbTable_AB');
</code>```

答:
What about something like this (this is slight modification of the answer by Vika):</p>

```<code>$model = new Model_DbTable_A();
$row = $model->find($id)->current(); // lite shortcut to get $row by $id

// get select object
$select = $model->select()->where('i.published = ?', true);

// fetch rows in B through A_B table where A_B.published is true
$b = $row->findManyToManyRowset('Model_DbTable_B', 'Model_DbTable_AB', null, null, $select);
</code>```

Body:
Is there a way I can do a condition on the join table with a many to many in ZF ?

For example I have table A | A_B |B

And B has columns A_ID | B_ID | PUBLISHED

$model = new Model_DbTable_A();
$select = $model->select()->where('id = ?', $id);
$row = $model->fetchRow($select);
$b = $row->findManyToManyRowset('Model_DbTable_B', 'Model_DbTable_AB');

Body:
What about something like this (this is slight modification of the answer by Vika):

$model = new Model_DbTable_A();
$row = $model->find($id)->current(); // lite shortcut to get $row by $id

// get select object
$select = $model->select()->where('i.published = ?', true);

// fetch rows in B through A_B table where A_B.published is true
$b = $row->findManyToManyRowset('Model_DbTable_B', 'Model_DbTable_AB', null, null, $select);


问:
ARcore and mobile-vision
I need to create an android app doing mainly two things.

1) Detect price and barcode

2) Creating AR content around the detected price/barcode

For the detection part, I use google mobile-vision and for the AR part I use ARcore. The problem I have is that Arcore doesnt allow auto focus so I dont have a good enough resolution to read the prices or bar codes.

So I was wondering if there was a standard way to do text recognition and AR in the same app.

Thank you.

答:
I haven't used ARcore, but have done a reasonable amount of detection. This was mostly done using a surface view extension showing and initialising a camera1 api view with detection interface and callbacks.

It is difficult to tell what might be going wrong without any code available or how you have gone about this, any chance you could provide some?

Title: ARcore and mobile-vision


问:
Updating state within setTimeout (React & React-Native)
What I've been trying to achieve are to update state and to update the same state again, based on Javascript's timer.

The reason why I can't achieve this seems to be the nature of state in React.js.

Here is a snippet of my experimentation...

```<code>render() {
    if (this.props.hasError) {
        setTimeout(function(){this.setState({showWarning: true}); }.bind(this), 3000);
    }
    return (
      <View>
        <Blah warning={this.state.showWarning} />
      </View>
    );
}
</code>```

So, the objective is to change state for only just a few seconds if there is a specific props provided.

This approach seems to hit the limit of updating states, if this.props.hasError gets updated too frequently.

Apologies if this question is too basic.
Any suggestion will be appreciated.

答:
There are two purposes. One is to change the background color of this
  component for 3 seconds, the other is to show a message, which is
  located in  (again, for 3 seconds)

Since you only want these changes to show for 3 seconds, you have to set them first, and then set the state to its opposite after 3 seconds using setTimeout.

Judging from your code, this.props.hasError is a boolean so we can set showWarning with that initially:

```<code>constructor(props){
  super(props);
  this.state = {showWarning: this.props.hasError}
}
</code>```

When the component renders, it will show the current state and after 3 seconds, we will change the state:

```<code>componentDidMount(){
  setTimeout(() => {
    this.setState({showWarning: false});
  }, 3000);
}
</code>```

Body:
What I've been trying to achieve are to update state and to update the same state again, based on Javascript's timer.

The reason why I can't achieve this seems to be the nature of state in React.js.

Here is a snippet of my experimentation...

render() {
    if (this.props.hasError) {
        setTimeout(function(){this.setState({showWarning: true}); }.bind(this), 3000);
    }
    return (
      <View>
        <Blah warning={this.state.showWarning} />
      </View>
    );
}

So, the objective is to change state for only just a few seconds if there is a specific props provided.

This approach seems to hit the limit of updating states, if this.props.hasError gets updated too frequently.

Apologies if this question is too basic.
Any suggestion will be appreciated.

Body:
There are two purposes. One is to change the background color of this
  component for 3 seconds, the other is to show a message, which is
  located in  (again, for 3 seconds)

Since you only want these changes to show for 3 seconds, you have to set them first, and then set the state to its opposite after 3 seconds using setTimeout.

Judging from your code, this.props.hasError is a boolean so we can set showWarning with that initially:

constructor(props){
  super(props);
  this.state = {showWarning: this.props.hasError}
}

When the component renders, it will show the current state and after 3 seconds, we will change the state:

componentDidMount(){
  setTimeout(() => {
    this.setState({showWarning: false});
  }, 3000);
}


问:
Mongodb get count of arrayitems over all collection items
I have a mongodb-collection like this:

```<code>{
    _id: 123,
    name: 'some name',
    category: 17,
    sizes: ['XS', 'S', 'XL']
},
{
    _id: 124,
    name: 'another name',
    category: 17,
    sizes: ['S', 'L', '2XL']
}
</code>```

I need two different approaches. First one: How many items per size are available in a specific category?

```<code>{
    17: {
        XS: 0,
        S:  19,
        M:  100
    },
    39: {
        XS: 5,
        ...
    }
}
</code>```

A solution, which just shows if an item in the size is available would also be possible:

```<code>{
    17: {
        XS: false,
        S:  true,
        M:  true,
        ...
    },
    39: {
        XS: true,
        ...
    }
}
</code>```

Second problem: I need the same, but after performing a full-text-search on a name.

I've tried to aggregate over the fields, but I'm a bit lost on how to perform that on the array.

Any help appreciated.

Update:

With help from this answer, I'm one step closer:

```<code>db.so.aggregate(
    [
        // First, filter by name or something else
        // this could also include the category
        {
            $match: {
                'name': {
                    $regex: /other.*/i
                }
            }
        },

        // explode the sizes-array into single documents
        { '$unwind': '$sizes' },

        // group and count
        { '$group': {
            '_id': '$sizes',
            'count': { '$sum': 1 }
        }}
    ]
)
</code>```

Still missing: do this by category

答:
Here is how you can pretty much get to the exact output document you suggested:

```<code>db.so.aggregate({
    $unwind: "$sizes" // flatten the sizes array
}, {
    $group: {
        _id: { // group by both category and sizes
            category: "$category",
            size: "$sizes"
        },
        count: {
           $sum: 1 // count number of documents per bucket
        }
    }
}, {
    $group: {
        _id: "$_id.category", // second grouping to get entries per category
        sizes: {
           $push: { k: "$_id.size", v: "$count" } // create an array of key/value pairs which we will need in this exact shape in the next stage
        }
    }
}, {
    $project: {
        "magic": {
            $arrayToObject: // transform the key/value pair we generate below into a document
            [[{
                // the $substr is a hack to transform the numerical category (e.g. 17)
                // into a string (not nice, probably not supported but working for now...)
                // which is needed for the above $arrayToObject to work
                k: { $substr: [ "$_id", 0, -1 ] },
                v: {
                    $arrayToObject: "$sizes" // turn the key/value pairs we created in the previous pipeline stage into a document
                }
            }]]
        }
    }
}, {
    $replaceRoot: {
        newRoot: "$magic" // promote our "magic" field to the document root
    }
})
</code>```

Please note that while this gives you the right output, I would not necessarily suggest going down that route since the aggregation pipeline is pretty hefty with quite some magic built into it for very little measurable benefit. So if you can accept an output structure like the one suggested by @Alex P. then this will certainly be easier to understand and maintain and faster as well.

With respect to your second scenario: You can add any number of preliminary $match stages before the $unwind stage to filter out any superfluous data.

Body:
I have a mongodb-collection like this:

{
    _id: 123,
    name: 'some name',
    category: 17,
    sizes: ['XS', 'S', 'XL']
},
{
    _id: 124,
    name: 'another name',
    category: 17,
    sizes: ['S', 'L', '2XL']
}

I need two different approaches. First one: How many items per size are available in a specific category?

{
    17: {
        XS: 0,
        S:  19,
        M:  100
    },
    39: {
        XS: 5,
        ...
    }
}

A solution, which just shows if an item in the size is available would also be possible:

{
    17: {
        XS: false,
        S:  true,
        M:  true,
        ...
    },
    39: {
        XS: true,
        ...
    }
}

Second problem: I need the same, but after performing a full-text-search on a name.

I've tried to aggregate over the fields, but I'm a bit lost on how to perform that on the array.

Any help appreciated.

Update:

With help from this answer, I'm one step closer:

db.so.aggregate(
    [
        // First, filter by name or something else
        // this could also include the category
        {
            $match: {
                'name': {
                    $regex: /other.*/i
                }
            }
        },

        // explode the sizes-array into single documents
        { '$unwind': '$sizes' },

        // group and count
        { '$group': {
            '_id': '$sizes',
            'count': { '$sum': 1 }
        }}
    ]
)

Still missing: do this by category

Body:
Here is how you can pretty much get to the exact output document you suggested:

db.so.aggregate({
    $unwind: "$sizes" // flatten the sizes array
}, {
    $group: {
        _id: { // group by both category and sizes
            category: "$category",
            size: "$sizes"
        },
        count: {
           $sum: 1 // count number of documents per bucket
        }
    }
}, {
    $group: {
        _id: "$_id.category", // second grouping to get entries per category
        sizes: {
           $push: { k: "$_id.size", v: "$count" } // create an array of key/value pairs which we will need in this exact shape in the next stage
        }
    }
}, {
    $project: {
        "magic": {
            $arrayToObject: // transform the key/value pair we generate below into a document
            [[{
                // the $substr is a hack to transform the numerical category (e.g. 17)
                // into a string (not nice, probably not supported but working for now...)
                // which is needed for the above $arrayToObject to work
                k: { $substr: [ "$_id", 0, -1 ] },
                v: {
                    $arrayToObject: "$sizes" // turn the key/value pairs we created in the previous pipeline stage into a document
                }
            }]]
        }
    }
}, {
    $replaceRoot: {
        newRoot: "$magic" // promote our "magic" field to the document root
    }
})

Please note that while this gives you the right output, I would not necessarily suggest going down that route since the aggregation pipeline is pretty hefty with quite some magic built into it for very little measurable benefit. So if you can accept an output structure like the one suggested by @Alex P. then this will certainly be easier to understand and maintain and faster as well.

With respect to your second scenario: You can add any number of preliminary $match stages before the $unwind stage to filter out any superfluous data.


问:
Creating WooCommerce product variation adds an empty attribute value
When adding variations to a WooCommerce product it is adding in a blank attribute. Meaning that when I try to add my own attribute it gets appended to an existing array.

Example code I am running:

```<code>$product_variation = wc_get_product( $variation_id );
$product_variation->set_attributes(array('attribute_pa_varinfo' => 'blue'));
$product_variation->save();
</code>```

Then when I var_dump($product_variation); I get the following:

```<code>["attributes"]=>
array(2) {
  [0]=>
  string(0) ""
  ["pa_varinfo"]=>
  string(4) "5034"
}
</code>```

So when I view the product in WooCommerce admin all my variations are there but the attribute is stuck at "any option" for all of them.

The weird thing is when I then "update" the product from wp-admin all of the variations then get the correct attribute selected.

Has anyone encountered this before or got any ideas of what I can do?

As another example, if I run the following:

```<code>$product_variation = wc_get_product( $variation_id );
$product_variation->set_attributes( array ( 'simon' => 'confused' ) );
$product_variation->save();
var_dump($product_variation->get_attributes());
</code>```

This returns:

```<code>array(2) {
 [0]=> string(0) ""
 ["simon"]=> string(8) "confused"
}
</code>```

Where does the first item come from? I can't seem to clear it.

答:
Update (related to your update and comments)

To resume (our comments): The product attribute exist. Also all terms for this attribute are defined and set in the parent variable product (in the "Attribute" settings tab)

I have made some tests:

I have create a new 'Varinfo" attribute (pa_varinfo) with 4 values (term names):
104 mm, 110 mm, 130 mm and 140 mm (so term slugs are like 104-mm…).

I have created a new variable product with one empty variation (nothing defined for this variation) and alter saving the select field shows:

When using this code (similar to yours):

```<code>$parent_product = wc_get_product( 738 ); // Get the variable product
$variation_ids = $parent_product->get_children(); // Get all children variations (Here only one)

// Iterating through each variation
foreach( $variation_ids as $variation_id ){
    $variation = wc_get_product($variation_id);
    $variation->set_attributes(array('pa_varinfo' => '104-mm'));
    $variation->save();
}
</code>```

it's just working for me and I get the selected value in backend for this variation:

Note that I am using the taxonomy name for the attribute and the term SLUG in the array…

So I don't know where you are doing something wrong…

This happens when you set an attribute term that doesn't exist and/or is not registered as a post term of the parent variable product. You can try this:

```<code>// Get an instance of the WC_Product_Variation object
$variation = wc_get_product( $variation_id );

// Initialising variables
$taxonomy = 'pa_varinfo'; // The taxonomy
$term_name = 'Blue'; // The term "NAME"

// Check if the term exist and if not we create it.
if( ! term_exists( $term_name, $taxonomy ) )
    wp_insert_term( $term_name, $taxonomy );

// Get an instance of the WP_Term object
$term = get_term_by( 'name', $term_name, $taxonomy );

// Get the post terms names from the parent variable product.
$post_term_names =  wp_get_post_terms( $variation->get_parent_id(), $taxonomy, array('fields' => 'names') );

// Check if the post term exist and if not we set it in the parent variable product.
if( ! in_array( $term_name, $post_term_names ) )
    wp_set_post_terms( $variation->get_parent_id(), $term_name, $taxonomy, true );

// Now you can set the term for the attribute in your variation
$variation->set_attributes( array( $taxonomy => $term->slug ) );
$variation->save(); // Registering the data

// Get an instance of the parent WC_Product_Variable object
$parent_product = wc_get_product( $variation->get_parent_id() );

// Sync the data of the variation in the parent variable product
$parent_product->sync( $variation_id );
</code>```

This is tested and works

Assuming that you have already created the appended attribute in WooCommerce…, you will get:

Body:
When adding variations to a WooCommerce product it is adding in a blank attribute. Meaning that when I try to add my own attribute it gets appended to an existing array.

Example code I am running:

$product_variation = wc_get_product( $variation_id );
$product_variation->set_attributes(array('attribute_pa_varinfo' => 'blue'));
$product_variation->save();

Then when I var_dump($product_variation); I get the following:

["attributes"]=>
array(2) {
  [0]=>
  string(0) ""
  ["pa_varinfo"]=>
  string(4) "5034"
}

So when I view the product in WooCommerce admin all my variations are there but the attribute is stuck at "any option" for all of them.

The weird thing is when I then "update" the product from wp-admin all of the variations then get the correct attribute selected.

Has anyone encountered this before or got any ideas of what I can do?

As another example, if I run the following:

$product_variation = wc_get_product( $variation_id );
$product_variation->set_attributes( array ( 'simon' => 'confused' ) );
$product_variation->save();
var_dump($product_variation->get_attributes());

This returns:

array(2) {
 [0]=> string(0) ""
 ["simon"]=> string(8) "confused"
}

Where does the first item come from? I can't seem to clear it.

Body:
Update (related to your update and comments)

To resume (our comments): The product attribute exist. Also all terms for this attribute are defined and set in the parent variable product (in the "Attribute" settings tab)

I have made some tests:

I have create a new 'Varinfo" attribute (pa_varinfo) with 4 values (term names):
104 mm, 110 mm, 130 mm and 140 mm (so term slugs are like 104-mm…).

I have created a new variable product with one empty variation (nothing defined for this variation) and alter saving the select field shows:

When using this code (similar to yours):

$parent_product = wc_get_product( 738 ); // Get the variable product
$variation_ids = $parent_product->get_children(); // Get all children variations (Here only one)

// Iterating through each variation
foreach( $variation_ids as $variation_id ){
    $variation = wc_get_product($variation_id);
    $variation->set_attributes(array('pa_varinfo' => '104-mm'));
    $variation->save();
}

it's just working for me and I get the selected value in backend for this variation:

Note that I am using the taxonomy name for the attribute and the term SLUG in the array…

So I don't know where you are doing something wrong…

This happens when you set an attribute term that doesn't exist and/or is not registered as a post term of the parent variable product. You can try this:

// Get an instance of the WC_Product_Variation object
$variation = wc_get_product( $variation_id );

// Initialising variables
$taxonomy = 'pa_varinfo'; // The taxonomy
$term_name = 'Blue'; // The term "NAME"

// Check if the term exist and if not we create it.
if( ! term_exists( $term_name, $taxonomy ) )
    wp_insert_term( $term_name, $taxonomy );

// Get an instance of the WP_Term object
$term = get_term_by( 'name', $term_name, $taxonomy );

// Get the post terms names from the parent variable product.
$post_term_names =  wp_get_post_terms( $variation->get_parent_id(), $taxonomy, array('fields' => 'names') );

// Check if the post term exist and if not we set it in the parent variable product.
if( ! in_array( $term_name, $post_term_names ) )
    wp_set_post_terms( $variation->get_parent_id(), $term_name, $taxonomy, true );

// Now you can set the term for the attribute in your variation
$variation->set_attributes( array( $taxonomy => $term->slug ) );
$variation->save(); // Registering the data

// Get an instance of the parent WC_Product_Variable object
$parent_product = wc_get_product( $variation->get_parent_id() );

// Sync the data of the variation in the parent variable product
$parent_product->sync( $variation_id );

This is tested and works

Assuming that you have already created the appended attribute in WooCommerce…, you will get:


问:
How to read arrays to form a matrix from file using numpy
I have a file with data as:
2 arrays in each row. Total= 10,000 rows.

```<code>[1,2,3,4,5][2,4,6,8,10]
[3,6,9,12,24][6,12,18,24,48]
....]
</code>```

I am planning to give this input to Linear Regression in the fit command.
I am having issue how to construct a matrix with entries.

I am looking at constructing Array (2 by x) like:

```<code>x=[
    [1,2,3,4,5]
    [3,6,9,12,24]
    ....]

y=
  [[2,4,6,8,10]
   [6,12,18,24,48]
    ....]
</code>```

so that I can give to the fit command as input.

I see numpy.fromfile is used to get the binary data.
can I use it for lists?

https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.fromfile.html

答:
Here is Solution

```<code>f = open("test.txt","r")
x = []
y = []
for i in f.readlines():
    split_values = i.split("][")
    s1 = split_values[0].replace('[','')
    s2 = split_values[1].replace(']','')
    s1_split = s1.split(",")
    s2_split = s2.split(",")
    s1_split = map(int, s1_split)
    s2_split = map(int, s2_split)
    x.append(s1_split)
    y.append(s2_split)
print(x)
print(y)
</code>```

Body:
I have a file with data as:
2 arrays in each row. Total= 10,000 rows.

[1,2,3,4,5][2,4,6,8,10]
[3,6,9,12,24][6,12,18,24,48]
....]

I am planning to give this input to Linear Regression in the fit command.
I am having issue how to construct a matrix with entries.

I am looking at constructing Array (2 by x) like:

x=[
    [1,2,3,4,5]
    [3,6,9,12,24]
    ....]

y=
  [[2,4,6,8,10]
   [6,12,18,24,48]
    ....]

so that I can give to the fit command as input.

I see numpy.fromfile is used to get the binary data.
can I use it for lists?

https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.fromfile.html

Body:
Here is Solution

f = open("test.txt","r")
x = []
y = []
for i in f.readlines():
    split_values = i.split("][")
    s1 = split_values[0].replace('[','')
    s2 = split_values[1].replace(']','')
    s1_split = s1.split(",")
    s2_split = s2.split(",")
    s1_split = map(int, s1_split)
    s2_split = map(int, s2_split)
    x.append(s1_split)
    y.append(s2_split)
print(x)
print(y)


问:
log4j2: Include PID
I'm using log4j2, and running multiple instances of the same code in different processes (ie different JVMs) at the same time.  I'd like all processes to log to the same file, interleaved  How can I configure (via log4j2.xml) to output the PID, so that the different processes can be distinguished in the logs?</p>

答:
There is a plugin ProcessIdPatternConverter in log4j2-core since version 2.9 that does exactly this.

just setting %pid or %processId in the pattern layout logs it.

log4j documentation: https://logging.apache.org/log4j/2.x/manual/layouts.html

Title: log4j2: Include PID


问:
how to put mean lines in ggplot?
I am try to do a plot whith means lines by group (in ggplot), and i have my code like this

```<code>ggplot(gama, aes(x = distancia, y= glipidoscmtejido, colour= estado)) +
geom_point(position=position_dodge(.5), alpha= 1, size=3) +
geom_crossbar(data=gama,aes(x=distancia,ymin=mean(glipidoscmtejido),
ymax=mean(glipidoscmtejido),y=mean(glipidoscmtejido),colour=estado), width = 0.5)
</code>```

and I get this

but i need the mean line by distancia and by estado. how can i make it?

thanks.

答:
How about this using stat_summary to plot the means per estado per distancia:

```<code># Generate some sample data
set.seed(2017);
df <- cbind.data.frame(
    x = rnorm(100),
    estado = sample(c("sana", "lesionada"), 100, replace = T),
    distancia = sample(c("0-1", "2.5-3.5", "5.6"), 100, replace = T));

require(ggplot2);
ggplot(df, aes(x = distancia, y = x, colour = estado)) +
    geom_point(position = position_dodge(width = 0.3)) +
    stat_summary(
        fun.y = mean,
        geom = "errorbar",
        aes(ymax = ..y.., ymin = ..y..),
        position = position_dodge(width = 0.3),
        width = 0.25);
</code>```

Title: how to put mean lines in ggplot?

Body:
I am try to do a plot whith means lines by group (in ggplot), and i have my code like this

ggplot(gama, aes(x = distancia, y= glipidoscmtejido, colour= estado)) +
geom_point(position=position_dodge(.5), alpha= 1, size=3) +
geom_crossbar(data=gama,aes(x=distancia,ymin=mean(glipidoscmtejido),
ymax=mean(glipidoscmtejido),y=mean(glipidoscmtejido),colour=estado), width = 0.5)

and I get this

but i need the mean line by distancia and by estado. how can i make it?

thanks.

Body:
How about this using stat_summary to plot the means per estado per distancia:

# Generate some sample data
set.seed(2017);
df <- cbind.data.frame(
    x = rnorm(100),
    estado = sample(c("sana", "lesionada"), 100, replace = T),
    distancia = sample(c("0-1", "2.5-3.5", "5.6"), 100, replace = T));

require(ggplot2);
ggplot(df, aes(x = distancia, y = x, colour = estado)) +
    geom_point(position = position_dodge(width = 0.3)) +
    stat_summary(
        fun.y = mean,
        geom = "errorbar",
        aes(ymax = ..y.., ymin = ..y..),
        position = position_dodge(width = 0.3),
        width = 0.25);


问:
awk: take entries from file and add values in between
I have the following file:

```<code>2    some
5    some
8    some
10   thing
15   thing
19   thing
</code>```

Now I want to end up with entries, where for "some" 2,5,8 correspond to rows where there is a 1, everything else is 0. It doesn't matter how many rows there are. This means for "some":

```<code>0
1
0
0
1
0
0
1
0
0
</code>```

and for "thing"

```<code>0
0
0
0
0
0
0
0
0
1
0
0
0
0
1
0
0
0
1
0
</code>```

Is this possible in a quick way with awk? I mean with something like:

```<code>awk '{for(i=1;i<=10;i++) entries[$i]=0 for(f=0;<=NF;f++) entries[$f]=1' testfile.txt
</code>```

答:
Something like this seems to work in order to produce "some" data:

```<code>$ cat file1
2    some
5    some
8    some
10   thing
15   thing
19   thing

$ awk 'max<$1 && $2=="some"{max=$1;b[$1]=1}END{for (i=1;i<=max;i++) print (i in b?1:0)}' file1
0
1
0
0
1
0
0
1
</code>```

Similarly , this one works for "thing" data

```<code>$ awk 'max<$1 && $2=="thing"{max=$1;b[$1]=1}END{for (i=1;i<=max;i++) print (i in b?1:0)}' file1
</code>```

Alternativelly, as mentioned by glennjackman  in comments we could use an external variable to select between some or thing:

```<code>$ awk -v word="some" 'max<$1 && $2==word{max=$1;b[$1]=1}END{for (i=1;i<=max;i++) print (i in b?1:0)}' file1
# for thing just apply awk -v word="thing"
</code>```

You can achieve better parameterizing using an awk variable like this:

```<code>$ w="some" #selectable / set by shell , by script , etc
$ awk -v word="$w" 'max<$1 && $2==word{max=$1;b[$1]=1}END{for (i=1;i<=max;i++) print (i in b?1:0)}' file1
</code>```

Body:
I have the following file:

2    some
5    some
8    some
10   thing
15   thing
19   thing

Now I want to end up with entries, where for "some" 2,5,8 correspond to rows where there is a 1, everything else is 0. It doesn't matter how many rows there are. This means for "some":

0
1
0
0
1
0
0
1
0
0

and for "thing"

0
0
0
0
0
0
0
0
0
1
0
0
0
0
1
0
0
0
1
0

Is this possible in a quick way with awk? I mean with something like:

awk '{for(i=1;i<=10;i++) entries[$i]=0 for(f=0;<=NF;f++) entries[$f]=1' testfile.txt

Body:
Something like this seems to work in order to produce "some" data:

$ cat file1
2    some
5    some
8    some
10   thing
15   thing
19   thing

$ awk 'max<$1 && $2=="some"{max=$1;b[$1]=1}END{for (i=1;i<=max;i++) print (i in b?1:0)}' file1
0
1
0
0
1
0
0
1

Similarly , this one works for "thing" data

$ awk 'max<$1 && $2=="thing"{max=$1;b[$1]=1}END{for (i=1;i<=max;i++) print (i in b?1:0)}' file1

Alternativelly, as mentioned by glennjackman  in comments we could use an external variable to select between some or thing:

$ awk -v word="some" 'max<$1 && $2==word{max=$1;b[$1]=1}END{for (i=1;i<=max;i++) print (i in b?1:0)}' file1
# for thing just apply awk -v word="thing"

You can achieve better parameterizing using an awk variable like this:

$ w="some" #selectable / set by shell , by script , etc
$ awk -v word="$w" 'max<$1 && $2==word{max=$1;b[$1]=1}END{for (i=1;i<=max;i++) print (i in b?1:0)}' file1