# How to convert matrix?

I have an array like this:

``````
\$start = array(
array('a', 'b', 'c'),
array('b', 'c'),
array('a', 'c')
);

``````

and I want convert to:

``````
\$end = array(
array('a' => 1, 'b' => 1, 'c' => 1),
array('a' => 0, 'b' => 1, 'c' => 1),
array('a' => 1, 'b' => 0, 'c' => 1)
);

``````

It means that each element in \$start will be key in \$end. If key appears in \$start, value is 1 and 0 if not. What do all you think?

Hi there,

Here’s my solution.
I’m still learning PHP (normally I work in Ruby), so I would be really grateful for any constructive criticism / pointers the rest of you could give me.

``````<?php
function convertArray(\$start){
\$end = array();
\$unique_keys = array();

// Get a list of all possible keys
for (\$row = 0; \$row < count(\$start); \$row++){
for (\$col = 0; \$col < count(\$start[\$row]); \$col++){
array_push(\$unique_keys, \$start[\$row][\$col]);
}
}
\$unique_keys = array_unique(\$unique_keys);
sort(\$unique_keys);

// Create new array using these keys
for (\$row = 0; \$row < count(\$start); \$row++){
for (\$col = 0; \$col < count(\$start[\$row]); \$col++){
\$temp_array = array();
foreach (\$unique_keys as \$key){
\$temp_array[\$key] = in_array(\$key, \$start[\$row])? '1' : '0';
}
}
array_push(\$end, \$temp_array);
}
return(\$end);
}

\$start = array(
array('a', 'b', 'c'),
array('b', 'c'),
array('a', 'c')
);

print_r(convertArray(\$start));
``````

This outputs:

``````Array ( [0] => Array ( [a] => 1 [b] => 1 [c] => 1 ) [1] => Array ( [a] => 0 [b] => 1 [c] => 1 ) [2] => Array ( [a] => 1 [b] => 0 [c] => 1 ) )
``````

Do you know for sure that \$start (or \$end) will always contain a fixed set of keys/values? Or a set of fixed keys/values you can divine/compute?

Hi! I’m still learning PHP too. Your solution is good. Thank a lot!

\$start (or \$end) is not contain a fixed set of keys and values, it’s based on database. Each subarray is a transaction (or an order).

And here is my solution:

main.php

``````
for(\$i=0; \$<count(\$database); \$i++){
\$transaction[] = getTransaction(\$candidates, \$database);
}

``````
``````
<?php
function minus_sets(\$a, \$b){

// number candidates in database
\$number_cans = count(\$a);
// number transactions database
\$number_trans = count(\$b);

for(\$i=0; \$i<count(\$a); \$i++){
\$same= 0;
for(\$j=0; \$j<count(\$b); \$j++){
if(\$a[\$i]==\$b[\$j]) \$same= 1;
}

if(!\$same){
\$tmp = \$tmp + 1;
\$c[\$tmp-1] = \$a[\$i];
}
}

return \$c;
}

//demo
//\$a = array(1, 2, 3, 4);
//\$b = array(2, 3, 4);
//\$minus = minus_set(\$a, \$b);
//print_r(\$minus);
//result is Array ( [0] => 1 )
?>

``````
``````
<?php

include('minus_sets.php');

function getTransaction(\$candidates, \$database){
// \$candidates minus \$database to take elements not in \$database
\$tmp = minus_sets(\$candidates, \$database);

for(\$i=0; \$i<count(\$candidates); \$i++){
if(!in_array(\$candidates[\$i], \$tmp)){
\$transaction[\$candidates[\$i]] = 1;
} else {
\$transaction[\$candidates[\$i]] = 0;
}
}

return \$transaction;
}

//\$candidates = array('a', 'b', 'c', 'd', 'e');
//\$database = array('a', 'b', 'c');

//\$transaction = getTransaction(\$candidates, \$database);
//print_r(\$transaction);
// result is Array ( [a] => 1 [b] => 1 [c] => 1 [d] => 0 [e] => 0 )
?>

``````

What do you think about my solution?

try “in_array”

there is full documentation at php.net

Maybe I have not understood your problem exactly, and re-using your test case (thanks, I like that, very thoughtful).

``````
\$a = array(1, 2, 3, 4);
\$b = array(2, 3, 4);

//\$minus = minus_set(\$a, \$b);
//print_r(\$minus);
//result is Array ( [0] => 1 )

\$c = array_diff(\$a, \$b);

var_dump(\$c);

// 0 => 1

``````

My idea is like Pullo’s idea but I don’t use array_push function so it may be longer than him. Thank!

I have a feeling my version might be reducable, but meh…

(Note: I changed the input variable to \$in)

``````\$keys = array_unique(array_merge_recursive(\$in))[0]; //Find all keys
\$values = array_combine(\$keys,array_pad(array(),count(\$keys),0)); //Fill with 0's. Creating a 'row' for the matrix.
\$replace = array_map(function(\$item) { return array_combine(\$item,array_pad(array(),count(\$item),1)); }, \$in); //All my 1's.
\$out = array_pad(array(),count(\$in),\$values); //Matrix of 0's.
\$out = array_replace_recursive(\$out,\$replace); //Put the 1's in the matrix.

``````

PHP belches array-to-string issues at me on my Replace line, but i’m not… entirely sure where i’m converting a string in there… anyway, it works.

Nice one StarLion. That’s really neat!
I hadn’t heard of `array_replace_recursive` or `array_merge_recursive`, so I’ve just been reading the docs for those.