I am looking for a way to take a multidimensional array and choose 2 random entries from the top level to create a new multidimensional array.
For example, if I have an array $data that looks like the below:
array (size=3)
0 =>
array (size=1)
0 =>
object(stdClass)[500]
public 'id' => int 2
public 'first_name' => string 'Mary' (length=4)
public 'last_name' => string 'Sweet' (length=5)
1 =>
array (size=1)
0 =>
object(stdClass)[501]
public 'id' => int 9
public 'first_name' => string 'Joe' (length=3)
public 'last_name' => string 'Bob' (length=3)
2 =>
array (size=1)
0 =>
object(stdClass)[502]
public 'id' => int 1
public 'first_name' => string 'Shag' (length=4)
public 'last_name' => string 'Well' (length=4)
How do I cut it up so that I take two of the three random entries, to get something like $data2:
array (size=2)
0 =>
array (size=1)
0 =>
object(stdClass)[500]
public 'id' => int 2
public 'first_name' => string 'Mary' (length=4)
public 'last_name' => string 'Sweet' (length=5)
1 =>
array (size=1)
0 =>
object(stdClass)[502]
public 'id' => int 1
public 'first_name' => string 'Shag' (length=4)
public 'last_name' => string 'Well' (length=4)
Use array_rand(). You could get more sophisticated depending on what you are doing, but here is the basic idea:
$randkeys = array_rand($data, 2);
$data2 = array($data[$randkeys[0]], $data[$randkeys[1]]);
See demo
Related
object(SimpleXMLElement)[803]
public 'row' =>
array (size=13)
0 =>
object(SimpleXMLElement)[797]
public '#attributes' =>
array (size=4)
'codeonimage' => string '01' (length=2)
'name' => string 'Крышка' (length=12)
'oem' => string '13711251885' (length=11)
'ssd' => string '$HgsQRnNPF0d$' (length=174)
public 'attribute' =>
array (size=2)
0 =>
object(SimpleXMLElement)[813]
public '#attributes' =>
array (size=3)
'key' => string 'amount' (length=6)
'name' => string 'Количество' (length=20)
'value' => string '1' (length=1)
1 =>
object(SimpleXMLElement)[814]
public '#attributes' =>
array (size=3)
'key' => string 'end_of_production' (length=17)
'name' => string 'end_of_production' (length=17)
'value' => string 'Не производтся с: 19871116' (length=40)
...
I'm trying to take all the 'oem' values from each SimpleXML element like:
array_column($simpleXMLObject->row, 'oem');
... and of course I get an error:
array_column() expects parameter 1 to be array, object given
There is another option with a full search. But maybe there is some more pretty way to do this?
I have the following repository:
class CustomerRepository extends EntityRepository
{
public function searchCustomer($criteria)
{
$q = $this->createQueryBuilder('c');
$q->join('TeamERPCustomerBundle:Company', 'o',
'WITH', 'c.company = o.id');
if (isset($criteria) and $criteria!=""){
$q->orWhere(sprintf("c.customer_name like '%s'", '%'.$criteria.'%'));
(...)
}
$q = $q->getQuery()->getResult(\Doctrine\ORM\AbstractQuery::HYDRATE_ARRAY);
return $q;
}
}
I call it from the controller as follows:
$result = $this->getDoctrine()->getManager()
->getRepository('TeamERPCustomerBundle:Customer')
->searchCustomer($customerInfo);
It returns an array of elements as follows:
array (size=20)
0 =>
array (size=9)
'id' => int 1
'customer_name' => string 'Abel' (length=4)
'address' => string 'Calle 52 # 60, % 3era y G. Quezada, Nuevo Sosa' (length=46)
'postal_address' => string '75100' (length=5)
'city_town_village' => string 'Las Tunas' (length=9)
'e_mail' => string 'abel#ltu.sld.cu' (length=15)
'land_line' => string '346386' (length=6)
'cell_phone' => null
'fax' => null
1 =>
array (size=2)
'id' => int 1
'company_name' => string 'Debswana' (length=8)
2 =>
array (size=9)
'id' => int 2
'customer_name' => string 'Kay' (length=3)
'address' => null
'postal_address' => null
'city_town_village' => null
'e_mail' => null
'land_line' => null
'cell_phone' => null
'fax' => null
3 =>
array (size=2)
'id' => int 3
'company_name' => string 'DTC' (length=3)
(...)
It gives one element of the array per object, but what I want it the classic mysql join; as result an array of elements of the same type. Something like mergin elements 1 and 2 together.
The other problem with this query is that is does not work like that classic join ether, it gives all the customers, but only the companies that are not repeated.
Can anyone help me to get a uniform array of elements?
Edit: I managed to find a solution:
$em = $this->getEntityManager();
$query = $em->createQuery('
SELECT c, i
FROM TeamERPCustomerBundle:Customer c
JOIN c.company i');
//$query->setParameter('id', '1'); With this is can add as many parameter as I need
return $query->getResult(\Doctrine\ORM\AbstractQuery::HYDRATE_ARRAY);
This returned something like this:
array (size=11)
0 =>
array (size=10)
'id' => int 1
'customer_name' => string 'Abel' (length=4)
'address' => string 'Calle 52 # 60, % 3era y G. Quezada, Nuevo Sosa' (length=46)
'postal_address' => string '75100' (length=5)
'city_town_village' => string 'Las Tunas' (length=9)
'e_mail' => string 'abel#ltu.sld.cu' (length=15)
'land_line' => string '346386' (length=6)
'cell_phone' => null
'fax' => null
'company' =>
array (size=2)
'id' => int 1
'company_name' => string 'Debswana' (length=8)
As you might have already appreciated this array is different from what I was getting before. so now I just have to go through the array and change it to what ever I want. for instance:
foreach ($result as $key => $value){
$result[$key]['company'] = $value['company']['company_name'];
}
Now we are talking. This Is kind of what I wanted:
array (size=11)
0 =>
array (size=10)
'id' => int 1
'customer_name' => string 'Abel' (length=4)
'address' => string 'Calle 52 # 60, % 3era y G. Quezada, Nuevo Sosa' (length=46)
'postal_address' => string '75100' (length=5)
'city_town_village' => string 'Las Tunas' (length=9)
'e_mail' => string 'abel#ltu.sld.cu' (length=15)
'land_line' => string '346386' (length=6)
'cell_phone' => null
'fax' => null
'company' => string 'Debswana' (length=8)
I have a multidimensional array $array that looks like this:
array (size=3)
0 =>
array (size=1)
0 =>
object(stdClass)[500]
public 'id' => int 2
public 'first_name' => string 'Mary' (length=4)
public 'last_name' => string 'Sweet' (length=5)
1 =>
array (size=1)
0 =>
object(stdClass)[501]
public 'id' => int 9
public 'first_name' => string 'Joe' (length=3)
public 'last_name' => string 'Bob' (length=3)
2 =>
array (size=1)
0 =>
object(stdClass)[502]
public 'id' => int 1
public 'first_name' => string 'Shag' (length=4)
public 'last_name' => string 'Well' (length=4)
I would like to be able to remove one of the items in the array by searching for values (not indexes).
So, I would like to remove the item in the array that has the first_name property of 'Joe'.
So if I removed it, the array would look like this:
array (size=2)
0 =>
array (size=1)
0 =>
object(stdClass)[500]
public 'id' => int 2
public 'first_name' => string 'Mary' (length=4)
public 'last_name' => string 'Sweet' (length=5)
1 =>
array (size=1)
0 =>
object(stdClass)[502]
public 'id' => int 1
public 'first_name' => string 'Shag' (length=4)
public 'last_name' => string 'Well' (length=4)
How would I be able to do this? Thanks.
Yes you could just use a foreach in this case. It will work just fine. Just use your search string needle and add an if inside the loop comparing the objects property firstname and the needle:
$first_name_search = 'Joe';
foreach ($array as $key => $value) {
$value = reset($value); // get that index 0 which is nested
if($value->first_name == $first_name_search) {
unset($array[$key]);
}
}
I use Zend Framework 2 with Doctrine 2. Here is my problem
The following returns Array of Objects
$results = $em->getRepository('MyProject\Domain\User')->find($id);
Returns:
array (size=4)
0 =>
object(My\Entity\User)[3]
private 'id' => int 1
private 'firstName' => string 'joe' (length=3)
private 'lastName' => string 'smith' (length=5)
1 =>
object(My\Entity\User)[3]
private 'id' => int 1
private 'firstName' => string 'joe' (length=3)
private 'lastName' => string 'smith' (length=5)
3 =>
object(My\Entity\User)[3]
private 'id' => int 1
private 'firstName' => string 'joe' (length=3)
private 'lastName' => string 'smith' (length=5)
4 =>
object(My\Entity\User)[3]
private 'id' => int 1
private 'firstName' => string 'joe' (length=3)
private 'lastName' => string 'smith' (length=5)
I want to convert it to Array of Arrays like so:
array (size=4)
0 =>
array (size=3)
['id'] => int 1
['firstName'] => string 'joe' (length=3)
['lastName'] => string 'smith' (length=5)
1 =>
array (size=3)
['id'] => int 1
['firstName'] => string 'joe' (length=3)
['lastName'] => string 'smith' (length=5)
2 =>
array (size=3)
['id'] => int 1
['firstName'] => string 'joe' (length=3)
['lastName'] => string 'smith' (length=5)
3 =>
array (size=3)
['id'] => int 1
['firstName'] => string 'joe' (length=3)
['lastName'] => string 'smith' (length=5)
I have tried the following:
$resultsArray = new \Doctrine\Common\Collections\ArrayCollection($results);
$resultsArray->toArray();
$resultsArray = new \Zend\Stdlib\ArrayObject($results);
$resultsArray->getArrayCopy();
Both return this:
array (size=4)
0 =>
object(My\Entity\User)[3]
private 'id' => int 1
private 'firstName' => string 'joe' (length=3)
private 'lastName' => string 'smith' (length=5)
1 =>
object(My\Entity\User)[3]
private 'id' => int 1
private 'firstName' => string 'joe' (length=3)
private 'lastName' => string 'smith' (length=5)
3 =>
object(My\Entity\User)[3]
private 'id' => int 1
private 'firstName' => string 'joe' (length=3)
private 'lastName' => string 'smith' (length=5)
4 =>
object(My\Entity\User)[3]
private 'id' => int 1
private 'firstName' => string 'joe' (length=3)
private 'lastName' => string 'smith' (length=5)
How can I accomplish this? What is the recommended way of doing it?
In its simplest form, the following does what you want
$qb = $em->getRepository('My\Entity\User')->createQueryBuilder('User');
$result = $qb->getQuery()->getArrayResult();
Normally you'd use a custom repository and add your DQL queries as methods as describe here in the docs
http://docs.doctrine-project.org/en/2.0.x/tutorials/getting-started-xml-edition.html#entity-repositories
Yet another way to code it, which I use:
//at the top of custom repository class
use Doctrine\Orm\Query;
//in the method
$dql = "SELECT u FROM MyProject\Domain\User u WHERE u.id = $id"
$query = $entityManager->createQuery($dql);
$users = $query->getResult(Query::HYDRATE_ARRAY);
//knowing the code you provided, this should give you an array of four arrays
Traditionally, I write a custom repository class and call a getArrayResult() inside of it
$dql = 'MYDQLHERE';
$query = $this->getEntityManager()->createQuery($dql);
$query->execute();
$result = $query->getArrayResult();
I believe your other option is custom hydration modes, although I don't have experience with them. http://docs.doctrine-project.org/en/latest/reference/dql-doctrine-query-language.html#custom-hydration-modes
I have the following Simple XML structure var_dump'ed:
var_dump($data) results in:
object(SimpleXMLElement)[269]
public 'columns' =>
object(SimpleXMLElement)[283]
public 'column' =>
array (size=11)
0 =>
object(SimpleXMLElement)[274]
public '#attributes' =>
array (size=2)
'name' => string 'test' (length=10)
'display' => string 'test ID' (length=11)
1 =>
object(SimpleXMLElement)[273]
public '#attributes' =>
array (size=2)
'name' => string 'blah' (length=8)
'display' => string 'blah' (length=8)
....
....
....
public 'row' =>
array (size=6)
0 =>
object(SimpleXMLElement)[270]
public '#attributes' =>
array (size=11)
'test' => string '3445543' (length=8)
'blah' => string 'Some Text' (length=13)
1 =>
object(SimpleXMLElement)[279]
public '#attributes' =>
array (size=11)
'test' => string '3445543' (length=8)
'blah' => string 'Some Text' (length=13)
2 =>
object(SimpleXMLElement)[278]
....
....
....
I shortened the output as you can see just to save room. But the row array contains 6 elements as you can see.
Now if I do this:
echo count($data->row); I get 6 as expected.
If I do this:
var_dump($data->row); I get this...
object(SimpleXMLElement)[270]
public '#attributes' =>
array (size=11)
'test' => string '3445543' (length=8)
'blah' => string 'Some Text' (length=13)
It prints out one element. No array.
Why would the count of the array return the right value but fetching the array only gets the first element of the array? How do I get all of the elements?