Sorry if there's too much code in this question. Arrays takes up a lot of space and I'm trying to explain this as thorough as I can. I'm trying to save all of the addresses user entered into one multidimensional array, so I could easily loop trough them after. Final result of what I'm trying to achieve in theory looks like this:
array(3) {[0]=>
array(4) {
["street_address"]=>
string(1) "a"
["city_name"]=>
string(1) "a"
["zip"]=>
string(1) "a"
["country_select"]=>
string(2) "LT"
}
[1]=>
array(4) {
["street_address"]=>
string(1) "b"
["city_name"]=>
string(1) "b"
["zip"]=>
string(1) "b"
["country_select"]=>
string(2) "LT"
}
[2]=>
array(4) {
["street_address"]=>
string(1) "c"
["city_name"]=>
string(1) "c"
["zip"]=>
string(1) "c"
["country_select"]=>
string(2) "LT"
}}
I could easily replicate this with simple code
$adresai = array();
$adresas =array(
'street_address' => 'a',
'city_name' => 'a',
'zip' => 'a',
'country_select' => 'a');
array_push($adresai, $adresas);
array_push($adresai, $adresas);
array_push($adresai, $adresas);
but when I'm trying to apply this logic in wordpress I get really strange layout, basically a mess.
array(1) {
[0]=>
array(2) {
[0]=>
array(2) {
[0]=>
array(4) {
["street_address"]=>
string(1) "a"
["city_name"]=>
string(1) "a"
["zip"]=>
string(1) "a"
["country_select"]=>
string(2) "LT"
}
[1]=>
array(4) {
["street_address"]=>
string(1) "b"
["city_name"]=>
string(1) "b"
["zip"]=>
string(1) "b"
["country_select"]=>
string(2) "LT"
}
}
[1]=>
array(4) {
["street_address"]=>
string(1) "c"
["city_name"]=>
string(1) "c"
["zip"]=>
string(1) "c"
["country_select"]=>
string(2) "LT"
}}}
My snippet for saving user entered address and merging with previous ones:
$adresai =get_user_meta(get_current_user_id(), 'stakliu_adresai');
$adresas =array(
'street_address' => $_POST['snr_gatve'],
'city_name' => $_POST['snr_miestas'],
'zip' => $_POST['snr_pastokodas'],
'country_select' => $_POST['snr_salis']);
if ($adresai == array()){
$adresai = $adresas;
}
else{
array_push($adresai, $adresas);
}
update_user_meta(get_current_user_id(),'stakliu_adresai', $adresai );
What am I doing wrong?
I would say part of your issue lies in:
if ($adresai == array()) {
$adresai = $adresas;
}else ...
You are planning on storing multiple addresses. An array of arrays. If the value does not exist, you are simply setting it to an array, as opposed to adding it to an array. Since you are expecting an empty array if nothing is set, you can simply push regardless, like so:
$adresai =get_user_meta(get_current_user_id(), 'stakliu_adresai');
$adresas = array(
'street_address' => $_POST['snr_gatve'],
'city_name' => $_POST['snr_miestas'],
'zip' => $_POST['snr_pastokodas'],
'country_select' => $_POST['snr_salis']
);
//if the array is empty, this address will become the first value
//if the array is not empty, this address will be added to the array
array_push($adresai, $adresas);
//save
update_user_meta(get_current_user_id(),'stakliu_adresai', $adresai );
So as naththedeveloper advised, I added parameter $single = true, which returns meta value without additional array "wrapping". But when meta is not set yet, function returns an empty string. To avoid errors I still had to use conditional statement. I finally got it working with this:
$adresai = get_user_meta(get_current_user_id(), 'stakliu_adresai', true);
$adresas = array(
'street_address' => $_POST['snr_gatve'],
'city_name' => $_POST['snr_miestas'],
'zip' => $_POST['snr_pastokodas'],
'country_select' => $_POST['snr_salis']);
// checking if value was not set earlier
if ($adresai == ''){
$adresai = array();
}
array_push($adresai, $adresas);
update_user_meta(get_current_user_id(),'stakliu_adresai', $adresai );
Related
I have two arrays and I want to have one array in result and I want also have all values of the arrays even if they has the same values.
I have tried array_combine(), but with the duplicate keys it is not possible.
I've also tried $array1 + $array2, but that isn't the desired result either.
These are my sample input arrays:
$array1 = array(10) {
[0]=> string(1) "1"
[1]=> string(0) ""
[2]=> string(2) "12"
[3]=> string(2) "41"
[4]=> string(1) "5"
[5]=> string(1) "6"
[6]=> string(0) ""
[7]=> string(2) "11"
[8]=> string(2) "23"
[9]=> string(2) "10" }
$array2 = array(11) {
[0]=> string(1) "A"
[1]=> string(1) "B"
[2]=> string(1) "C"
[3]=> string(1) "D"
[4]=> string(1) "E"
[5]=> string(1) "F"
[6]=> string(1) "G"
[7]=> string(1) "H"
[8]=> string(1) "I"
[9]=> string(2) "J"
[10]=> string(1) "K" }
I should have output data like this:
$array = array(11){
[1]=> string(1) "A"
[]=> string(1) "B"
[12]=> string(1) "C"
[41]=> string(1) "D"
[5]=> string(1) "E"
[6]=> string(1) "F"
[]=> string(1) "G"
[11]=> string(1) "H"
[23]=> string(1) "I"
[10]=> string(2) "J"
[]=> string(1) "K" }
If you want to combine the two arrays then you can use $array2's values as keys because they are unique (and it is the longer array so, $array1 won't get cut off).
$array1=["1","","12","41","5","6","","11","23","10"];
$array2=["A","B","C","D","E","F","G","H","I","J","K"];
foreach($array2 as $i=>$v){
$result[$v]=(isset($array1[$i])?$array1[$i]:NULL);
}
var_export($result);
Output:
array (
'A' => '1',
'B' => '',
'C' => '12',
'D' => '41',
'E' => '5',
'F' => '6',
'G' => '',
'H' => '11',
'I' => '23',
'J' => '10',
'K' => NULL,
)
Alternatively, you could pad $array1 then combine:
$array1=["1","","12","41","5","6","","11","23","10"];
$array2=["A","B","C","D","E","F","G","H","I","J","K"];
$array1=array_pad($array1,sizeof($array2),NULL);
$result=array_combine($array2,$array1);
You cannot use array_combine because array_combine expects the arrays to be the same size. And in fact, the output you ask for is not possible. Array keys need to be unique. You cannot have
[]=> string(1) "B"
[]=> string(1) "G"
[]=> string(1) "K"
as these would overwrite each other. You'd end up with only K.
An alternative would be to assign an array when there are multiple values per key, e.g.
[]=> array(3) ["B", "G", "K"]
There is no built-in function for this though. You'll have to manually iterate both arrays and assign the values as needed. A simple solution would be to use a MultipleIterator because it can easily deal with differently sized arrays:
$keys = new ArrayIterator(["", 1, "", 2, "", 3]);
$values = new ArrayIterator(["A", "B", "C", "D", "E", "F", "G"]);
$flags = MultipleIterator::MIT_NEED_ANY|MultipleIterator::MIT_KEYS_ASSOC;
$pairs = new MultipleIterator($flags);
$pairs->attachIterator($keys, 'key');
$pairs->attachIterator($values, 'value');
$combined = [];
foreach ($pairs as $pair) {
$key = $pair['key'];
$val = $pair['value'];
if (!isset($combined[$key])) {
$combined[$key] = $val;
continue;
}
if (!is_array($combined[$key])) {
$combined[$key] = [$combined[$key]];
}
$combined[$key][] = $val;
}
print_r($combined);
This would then produce:
Array
(
[] => Array
(
[0] => A
[1] => C
[2] => E
[3] => G
)
[1] => B
[2] => D
[3] => F
)
You can use array_merge like below:
print_r(array_merge($array1, $array2));
or you can use array_combine: array_combine(keys,values);
$fname=array("Peter","Ben","Joe");
$age=array("35","37","43");
$c=array_combine($fname,$age);
print_r($c);
Alert: But you can't duplicate the keys.
I have an array like this. I want remove elements with duplicate id and get sum of the count
array(3) {
[0]=>
array(3) {
["Id"]=>
string(1) "1"
["Name"]=>
string(1) "a"
["Count"]=>
string(1) "2"
}
[1]=>
array(3) {
["Id"]=>
string(1) "2"
["Name"]=>
string(1) "b"
["Count"]=>
string(1) "1"
}[2]=>
array(3) {
["Id"]=>
string(1) "1"
["Name"]=>
string(1) "a"
["Count"]=>
string(1) "1"
}
}
and I need to remove elements with duplicate id and get sum of the count as shown below
array(2) {
[0]=>
array(3) {
["Id"]=>
string(1) "1"
["Name"]=>
string(1) "a"
["Count"]=>
string(1) "3"
}[1]=>
array(3) {
["Id"]=>
string(1) "2"
["Name"]=>
string(1) "b"
["Count"]=>
string(1) "1"
}
}
I have gone through many examples.. but couldn't find an answer..
Unfortunately there is no way around looping. Assuming that Name is the same for the same Id or that you don't care about the value of Name:
foreach($array as $value) {
if(!isset($result[$value['Id']])) {
$result[$value['Id']] = $value;
} else {
$result[$value['Id']]['Count'] += $value['Count'];
}
}
// re-index if needed
$result = array_values($result);
Loop the array and build result array using Id as key
If the key Id doesn't exist create it
If it does exist add Count to the current Count
just create a new array, loop through current, create if doesnt exist, and insert values (sum) into new one
what are you doing with duplicates names?
example below. hope it will help.
<?php
$tArr = array(
array(
"Id" => "1",
"Name" => "a",
"Count" => "2",
),
array(
"Id" => "2",
"Name" => "b",
"Count" => "1",
),
array(
"Id" => "1",
"Name" => "a",
"Count" => "1",
)
);
$rez = array();
foreach ($tArr as $key => $element) {
if (empty($rez[$element["Id"]])) {
$rez[$element["Id"]] = $element;
} else {
$rez[$element["Id"]]["Count"] += $element["Count"];
}
}
var_dump($rez);
/** array (size=2)
1 =>
array (size=3)
'Id' => string '1' (length=1)
'Name' => string 'a' (length=1)
'Count' => int 3
2 =>
array (size=3)
'Id' => string '2' (length=1)
'Name' => string 'b' (length=1)
'Count' => string '1' (length=1)**/
Try this
$result = array_diff_assoc($arr, array_unique($arr));
print_r($result);
Im editing a plugin because I want to create a checkbox for the tags the plugin has. In this moment Ive got in a variable, this array:
array(9) { [129]=> object(EM_Tag)#84 (15) { ["id"]=> string(3) "129" ["term_id"]=> string(3) "129" ["name"]=> string(35) "Accessible for non-English speakers" ["slug"]=> string(11) "non-english" ["term_group"]=> string(1) "0" ["term_taxonomy_id"]=> string(3) "129" ["taxonomy"]=> string(10) "event-tags" ["description"]=> string(0) "" ["parent"]=> string(1) "0" ["count"]=> string(1) "0" ["fields"]=> array(0) { } ["required_fields"]=> array(0) { } ["feedback_message"]=> string(0) "" ["errors"]=> array(0) { } ["mime_types"]=> array(3) { [1]=> string(3) "gif" [2]=> string(3) "jpg" [3]=> string(3) "png" } } }
There are more tags but I just put one. I would like to generate a checkbox for each tag.
One solution is to iterate over the array that you provided and access the fields that way. I made a shortened array with proper indentation based on your example provided. It seems to be the same but let me know otherwise.
$array = array(
129 => array(
'id' => '129',
'name' => 'Accessible for non-English Speakers'
),
130 => array(
'id' => '130',
'name' => 'A second piece of information'
),
131 => array(
'id' => '131',
'name' => 'A third piece of information'
)
);
// Iterate over the array
foreach ($array as $c) {
// Access the required data
$id = $c['id'];
$name = $c['name'];
// Generate your checkbox
print "<input type='checkbox' name='$name' id='$id'>";
}
array(
[0]=> array(3)
{
[0]=> array(3)
{
["name"]=> string(1) "a" ,
["code"]=> string(3) "416" ,
["id"]=> string(2) "a1" ,
},
[1]=> array(3)
{
["name"]=> string(1) "a",
["code"]=> string(3) "522" ,
["id"]=> string(2) "a2",
},
[2]=> array(3)
{
["name"]=> string(1) "b" ,
["code"]=> string(3) "580" ,
["id"]=> string(2) "b1" ,
}
},
[1]=> array(3)
{
[0]=> array(3)
{
["name"]=> string(1) "a" ,
["code"]=> string(3) "416" ,
["id"]=> string(2) "a1" ,
},
[1]=> array(3)
{
["name"]=> string(1) "a" ,
["code"]=> string(3) "522" ,
["id"]=> string(2) "a2" ,
},
[2]=> array(3)
{
["name"]=> string(1) "b" ,
["code"]=> string(3) "899" ,
["id"]=> string(2) "b2",
}
}
);
I have array like this. All I need is for each array (e.g [0]=>array())
I will search for the arrays inside and get the array['code'] only for array set that has distinct name value.
Example for array[0]: I will get the array[0][2]['code'] because the array set of this particular array[0][2]['code'] has a unique 'name'
Assume in the below code $array is $arr[0] from your example:
$array = array(
array(
"name" => "a",
"code" => "416",
"id" => "a1"
),
array(
"name" => "a",
"code" => "522",
"id" => "a2"
),
array(
"name" => "b",
"code" => "580",
"id" => "b1"
)
);
$counts = array_count_values(
array_map(function (array $entry) { return $entry['name']; }, $array)
// or array_column($array, 'name') in PHP 5.5+
);
$uniqueNames = array_keys(
array_filter($counts, function ($count) { return $count == 1; })
);
$result = array_filter($array, function (array $entry) use ($uniqueNames) {
return in_array($entry['name'], $uniqueNames);
});
Not necessarily the super most efficient method, but straight forward and functional. It filters the array down to the entries where name exists only once. This may or may not fit your definition of "unique", it's rather unclear what variations in the input data you may have.
Hello i tried (permutated actually) every single way of inserting to in array in mongodb, nothing is working how im expecting it.
this is the structure of the document that i want to push into
["test123"]=>
array(6) {
["_id"]=>
string(7) "test123"
["products"]=>
array(1) {
[0]=>
array(9) {
["task_description"]=>
string(0) ""
["priority"]=>
string(4) "high"
["done"]=>
string(4) "true"
["extended_price"]=>
string(1) "0"
["unit_price"]=>
string(1) "0"
["qty"]=>
string(1) "0"
["description"]=>
string(18) "sample description"
["item"]=>
string(7) "Service"
["date_done"]=>
string(10) "2013-06-03"
}
}
["total"]=>
string(1) "0"
["tax"]=>
string(1) "0"
["discount"]=>
string(1) "0"
["currency"]=>
string(3) "EUR"
}
}
I want to push another array in the format of products[0] to products.
Here is the code that i try to do it with.
$collection->update(
array("_id" => $id),
// THIS REPLACES [0] ELEMENT IN ARRAY 'PRODUCTS' BUT I DONT WANT THAT
// array('$push' => array("products"=>array(0=>$data)))
// THIS IS NOT WORKING AT ALL
array('$push' => array('products' => $data))
);
What is the exact error you're seeing? Given the example document you shared, I can't reproduce either of your issues (products[0] being overwritten or the vague "this isn't working at all" comment).
I achieved the desired outcome with the following, which happens to match your code above:
$m = new MongoClient();
$c = $m->test->foo;
$c->drop();
// Create a document with a "p" array containing one embedded object
$c->insert(['p' => [['a' => 1, 'b' => 1]]]);
// This would add a second element to the "p" array, which would be
// a single-element array containing our embedded object
$c->update([], ['$push' => ['p' => [0 => ['a' => 2, 'b' => 2]]]]);
// This appends an embedded object to the "p" array
$c->update([], ['$push' => ['p' => ['a' => 2, 'b' => 2]]]);
// Debugging
var_export(iterator_to_array($c->find()));