Search code examples
pythonwordpressadvanced-custom-fields

Python Add to List From Advanced Custom Fields Query


I am attempting to query some options created in a Wordpress site that utilized an Advanced Custom Fields repeater and create a python list out of them.

I have the query just fine, but it returns typical ACF "option" repeater data in that, it's not stored as a serialized array but rather each field is a separate record that looks like this:

option_name option_value
options_updates_notifier_contact_list_0_un_c_email  kpirnie@example.com
options_updates_notifier_contact_list_0_un_c_name   Kevin
options_updates_notifier_contact_list_1_un_c_email  kpirnie+hub@example.com
options_updates_notifier_contact_list_1_un_c_name   Kevin 2
options_updates_notifier_contact_list_2_un_c_email  kpirnie+thehub@example.com
options_updates_notifier_contact_list_2_un_c_name   Kevin 3

My Code loops this, and gathers up the required elements based on some regex

# setup the regular expression to use
_re = r"options_updates_notifier_contact_list_(\d+)_un_c_(\w+)"
# hold our returnable list        _ret = []

# if there are records
if _rs is not None:
    # loop them
    for _r in _rs:
        # hold the field
        _field = _r[0]
        # hold the value
        _value = _r[1]
        # hold the RE match
        _match = re.search( _re, _field )
        # the index
        _idx = int( _match.group( 1 ) )
        # the name
        _the_name = _match.group( 2 )
        # insert at the set index
        _ret.insert( _idx, [ _idx, _the_name, _value ] )
        # this returns a IndexError: list index out of range
        #_ret[ int( _match.group( 1 ) ) ].extend( [ _match.group( 2 ), _value ] )

print( _ret )

Which returns me the following list:

[[0, 'name', 'Kevin'], [1, 'name', 'Kevin 2'], [2, 'name', 'Kevin 3'], [2, 'email', 'kpirnie+thehub@example.com'], [1, 'email', 'kpirnie+hub@example.com'], [0, 'email', 'kpirnie@example.com']]

My goal is to have the list be returned like this:

[
    [[0, 'name', 'Kevin'], [0, 'email', 'kpirnie@example.com']],
    [[1, 'name', 'Kevin 2'], [1, 'email', 'kpirnie+hub@example.com']],
    [[2, 'name', 'Kevin 3'], [2, 'email', 'kpirnie+thehub@example.com']]
]

Where each name|email combo is it's own list item. How can I do this?


Solution

  • If you start from your current result, you can sort, pair and validate your data like so:

    data = [
        [0, 'name', 'Kevin'], 
        [1, 'name', 'Kevin 2'], 
        [2, 'name', 'Kevin 3'], 
        [2, 'email', 'kpirnie+thehub@example.com'], 
        [1, 'email', 'kpirnie+hub@example.com'], 
        [0, 'email', 'kpirnie@example.com']
    ]
    
    # Sorting
    data = sorted(data, key=lambda item: item[0])
    
    # Pairing
    it = iter(data)
    data = [list(item) for item in zip(it, it)]
    
    # Validation
    assert(all(el[0] == item[0][0] for item in data for el in item))
    

    This is assuming that you will have 2 records per index value. If this condition is not fulfilled, the validation won't pass and will raise an exception.