Giter Site home page Giter Site logo

Is there a "unique" switch? about faker HOT 6 CLOSED

fzaninotto avatar fzaninotto commented on August 17, 2024
Is there a "unique" switch?

from faker.

Comments (6)

fzaninotto avatar fzaninotto commented on August 17, 2024

No, but it's a great idea. Look at #166 for inspiration.

from faker.

rogamoore avatar rogamoore commented on August 17, 2024

I will take a look! :)

from faker.

rogamoore avatar rogamoore commented on August 17, 2024

Ok, so I don't think the chaining approach would work in this case:

$faker->unique()->country - the unique method has no access to the result of country
$faker->country->unique() - doesn't work because country will return only the element

Idea 1

in Base.php

function unique($method, $parameters = array())  {
  // call $method with $parameters
  // keep track of the returned value for this method (where? static array?)
  // return value if not used before
}

Usage:

$faker->unique('country');
$faker->unique('randomElement', array(1, 2, 3));

possible problems:

  • $method will be called until there is a new value which will lead to:
    • an infinitive loop if there are less values available than calls to unique()
    • slow performance because the values may be generated randomly

Idea 2

in EntityPopulator.php

  • check if field is unique (Doctrine: ->isUniqueField()
  • generate entities but track the return values for this field
  • try to generate a new value if the value was already used

possible problems:

  • same as above

Idea 3

  • change all basic methods to accept a unique flag
  • create then an array copy of the possible values
  • use the copy to track changes (remove value from copy once used)
  • throw Exception if there is no more value left
    possible problems:
  • a lot of changes

Any thoughts?

from faker.

fzaninotto avatar fzaninotto commented on August 17, 2024

I do think a proxy object could do the trick. unique() would return an instance of a proxy object, embedding the generators. Each time a user calls a generator on this proxy, it would call the embedded generator and keep the result in an internal array. Something like:

class UniqueProxy
{
  protected $generator;
  protected $uniques = array();

  public function __construct(Faker\Generator $generator) 
  {
    $this->generator = $generator;
  }

  public function __call($name, $value)
  {
    if(!isset($this->uniques[$name])) {
      $this->uniques[$name] = array();
    }
    do {
      $res = call_user_func(array($this->generator, $name), $value);
    } while (in_array($res, $this->uniques[$name])) ;
    $this->uniques[$name][]= $res;

    return $res;
  }
}

Then $generator->unique() would return a UniqueProxy singleton, and I think it works. There are some limit cases to deal with (like when the provider doesn't exist), but if I write all the code then it's not your pull request anymore ;)

from faker.

rogamoore avatar rogamoore commented on August 17, 2024

Great approach! This solves the ugly syntax from my first idea. :)

There is still the infinite loop problem to solve. If you use this with e.g. safeColorName() which has 15 unique values and call it 20 times, on run 16 it will try forever to get a value that isn't already in the $uniquesarray.
One could set a limit of 1000 loops for each call and throw an exception, but this has a very dirty feeling.

Another thing is using this in combination with the ORM Populator class. As far as I understand the generator instance will be reused for all addEntity() calls. So if you want to populate more than one entity with unique countries, it will probably run out of fresh countries at some point.

I will keep this idea in mind and see if I can come up with an easy way to solve these problems.

from faker.

rogamoore avatar rogamoore commented on August 17, 2024

great!

from faker.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.