Home > Mobile >  How to sort array by array of order?
How to sort array by array of order?

Time:06-18

I have the following function that accepts array and order:

function toCSV($data, $order)
{

    $res = [];
    foreach ($data as $index =>  $row) {
        $str = [];
        foreach ($row as  $column) {
            foreach ($order as $key) {
                if ($column['key'] == $key)
                    $str[] =   $column;
            }
        }

        $res[$index] = $str;
    }

    return $res;
}

The $data is:

[[{"key":"num","value":"5132756002760855","indexrow":162,"columnindex":0}...]]

The $order is array of sequance:

$order = ['num', 'mm', 'yy', 'zip']

So, I try to sort first array by the second array. But it does not work for me. As result I get unsorted array.

Full $data array is:

[[{"key":"undetected","value":"","indexrow":25,"columnindex":0}],[{"key":"num","value":"5354562740628987","indexrow":64,"columnindex":0},{"key":"mmyy","value":"01\/26","indexrow":64,"columnindex":1}]]

CodePudding user response:

The if in the most inner loop will be true at some point and then the element is added, so the order doesn't change. Assuming you have only keys that appear in order. If you switch the two most inner loops it will work but it is not very efficient. O(nm) instead of O(n m).

function toCSV($data, $order) {
    $res = [];
    foreach ($data as $index =>  $row) {
        $map = [];
        $str = [];
        foreach ($row as  $column) {
            if (array_key_exists($column['key'], $map))
                $map[$column['key']][] = $column;
            else
                $map[$column['key']] = [$column];
        }
        foreach ($order as $key) {
            if (array_key_exists($key, $map))
                $str = array_merge($str, $map[$key]);
        }
        $res[$index] = $str;
    }
    return $res;
}

If a key can only exist once per row then you can simplify and don't have to use arrays in the map. Simplified version, also assuming each key in order appears once per column:

function toCSV($data, $order) {
    $res = [];
    foreach ($data as $index =>  $row) {
        $map = [];
        $str = [];
        foreach ($row as  $column)
            $map[$column['key']] = $column;
        foreach ($order as $key)
            $str[] = $map[$key];
            // to create key if it doesn't exist use the following:
            // $str[] = array_key_exists($key, $map) ? $map[$key] : [];
        $res[$index] = $str;
    }
    return $res;
}

Both versions will discard columns with keys not in $order.

  •  Tags:  
  • php
  • Related