Code Share - Page 8
Page 8 of 8 FirstFirst ... 678
Results 106 to 109 of 109

Thread: Code Share

  1. #106
    Pedantic Curmudgeon Weedpacket's Avatar
    Join Date
    Aug 2002
    Location
    General Systems Vehicle "Running Gear"
    Posts
    22,572
    Permutations!
    A couple of generators: pass one an array and it have it successively crank out different permutations of the array's elements. ("Different", that is, if all of the input array's elements are distinct.)

    One yields the permutations in lexicographic ("dictionary") order. Think of the array as a word written in some weird alphabet (its elements being the letters), and taking the order of letters in that word to be "alphabetical" (an English example of such a word would be "begins").
    Code:
    a b c
    a c b
    b a c
    b c a
    c a b
    c b a
    The other is a "minimum change" order. The permutations in each adjacent pair in the generated list differ by a single pair of swapped elements. Obviously, the swap has to yield a permutation that has not yet been seen, with the added proviso that the process doesn't get itself wedged into a corner where no swap can generate a new permutation. If there is a choice of swaps that could be made, the leftmost is picked.
    Code:
    a b c
    b a c
    c a b
    a c b
    b c a
    c b a
    So, here's the code. Note that minimum_change_permutations uses an auxiliary factorial function. Feel free to pick something more robust if you want to be generating such a sequence of permutations with more than 20 elements (which has given me something to think about...).

    PHP Code:
    function factorial($n)
    {
        
    // Note 21! > PHP_INT_MAX
        
    static $memo = [];
        if(!isset(
    $memo[$n]))
            
    $memo[$n] = array_product(range(1,$n));
        return 
    $memo[$n];
    }

    function 
    minimum_change_permutations($l)
    {
        
    $i 1;
        
    $p $l;
        
    $n count($l);
        
    $c array_fill(0$n 10);

        yield 
    $p;
        for(
    $t factorial($n); $t 1; --$t)
        {
            while(
    $c[$i] > $i)
            {
                
    $c[$i++] = 0;
            }
            
    $k = ($i 1) ? $c[$i];
            [
    $p[$i 1], $p[$k]] = [$p[$k], $p[$i 1]];
            ++
    $c[$i];
            
    $i 2;
            yield 
    $p;
        }
    }

    function 
    lexicographic_permutations($l)
    {
        
    $n count($l);
        if(
    $n == || $n == 1)
        {
            yield 
    $l;
        }
        elseif(
    $n == 2)
        {
            yield 
    $l;
            yield 
    array_reverse($l);
        }
        else
        {
            
    $table = [];
            for(
    $i 0$i $n; ++$i)
            {
                
    $new $l;
                
    $li $new[$i];
                unset(
    $new[$i]);
                foreach(
    lexicographic_permutations(array_values($new)) as $v)
                {
                    
    array_unshift($v$li);
                    yield 
    $v;
                }
            }
        }

    THERE IS AS YET INSUFFICIENT DATA FOR A MEANINGFUL ANSWER
    FAQs! FAQs! FAQs! Most forums have them!
    Search - Debugging 101 - Collected Solutions - General Guidelines - Getting help at all

  2. #107
    High Energy Magic Dept. NogDog's Avatar
    Join Date
    Aug 2006
    Location
    Ankh-Morpork
    Posts
    14,909
    Made a small extension to the PDO class to help DRY up my use of prepared statements: https://github.com/nogdog/pdoquery

    The actual PHP code is simply:
    PHP Code:
    <?php

    /**
     * Add a one-stop method for prepared query execution
     */
    class PDOQuery extends PDO
    {
        
    /**
         * Prepare and execute a query
         *
         * @param string $sql
         * @param Array $data  array(':place_holder_1' => 'value_1'[,...])
         * @return PDOStatement
         */
        
    public function preparedQuery($sql, Array $data=array())
        {
            
    $stmt $this->prepare($sql);
            if(
    $stmt == false)
            {
                throw new 
    Exception('Prepare failed:'.PHP_EOL.print_r($this-errorInfo()));
            }
            if((
    $result $stmt->execute($data)) == false)
            {
                throw new 
    Exception('Execute failed:'.PHP_EOL.print_r($stmt->errorInfo()));
            }
            return 
    $stmt;
        }
    }
    "Well done....Consciousness to sarcasm in five seconds!" ~ Terry Pratchett, Night Watch

    How to Ask Questions the Smart Way (not affiliated with this site, but well worth reading)

    My Blog
    cwrBlog: simple, no-database PHP blogging framework

  3. #108
    Pedantic Curmudgeon Weedpacket's Avatar
    Join Date
    Aug 2002
    Location
    General Systems Vehicle "Running Gear"
    Posts
    22,572
    This is more of a sketch of an idea. That idea is that "It would be nice to be able to call a method on an array of objects and have that method call mapped over all of the objects in the array." Like I have an array $clients and I want to call $client->getMessages('INFO', $channel) on each one.

    Writing it directly gives something like
    PHP Code:
    array_map(function($client)use($channel)
    {
        return 
    $client->getMessages('INFO'$channel);
    }, 
    $clients); 
    But that feels a bit messy for something I'd probably do a fair bit of. Notice the repetition of $client and $channel.

    For now I'm trying out this:
    PHP Code:
    function map_method($array)
    {
        return new class(
    $array)
        {
            private 
    $array;
            public function 
    __construct($array)
            {
                
    $this->array $array;
            }
            public function 
    __call($name$arguments)
            {
                return 
    array_map(function($element)use($name$arguments)
                {
                    return 
    $element->{$name}(...$arguments);
                }, 
    $this->array);
            }
        };

    Which lets me replace that array_map above with
    PHP Code:
    map_method($clients)->getMessages('INFO'$channel); 
    Last edited by Weedpacket; 12-08-2017 at 04:51 AM.
    THERE IS AS YET INSUFFICIENT DATA FOR A MEANINGFUL ANSWER
    FAQs! FAQs! FAQs! Most forums have them!
    Search - Debugging 101 - Collected Solutions - General Guidelines - Getting help at all

  4. #109
    Pedantic Curmudgeon Weedpacket's Avatar
    Join Date
    Aug 2002
    Location
    General Systems Vehicle "Running Gear"
    Posts
    22,572
    Okay, I just needed to flatten out an arbitrarily-nested array. Adding the limit condition was a last-minute decoration.
    PHP Code:

    function flatten_array($array$limit PHP_INT_MAX)
    {
        
    $recurse = function($array$limit)use(&$recurse)
        {
            if(
    $limit >= 0)
            {
                foreach(
    $array as $a)
                {
                    if(
    is_array($a))
                    {
                        yield from 
    $recurse($a$limit 1);
                    }
                    else
                    {
                        yield 
    $a;
                    }
                }
            }
            else
            {
                yield 
    $array;
            }
        };
        return 
    iterator_to_array($recurse($array$limit), false);
    }

    $array = [[1,2,3],[4,[5],6],7,8,[[[[[[[9]]],10]]]]];

    $f flatten_array($array2);
    var_export($f); 
    Last edited by Weedpacket; 12-31-2017 at 12:03 AM.
    THERE IS AS YET INSUFFICIENT DATA FOR A MEANINGFUL ANSWER
    FAQs! FAQs! FAQs! Most forums have them!
    Search - Debugging 101 - Collected Solutions - General Guidelines - Getting help at all

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •