How to replace an element in an array - php

I have a COLLECTION collflokks in MongoDB, sample Document is :-
{
"_id" : "b_8AUL",
"f_name" : "Pizza. Hut",
"f_lat" : "22.7523513",
"f_lng" : "75.9225847",
"c_uid" : "33",
"f_type" : NumberLong(3),
"members" : [
"42",
"43"
]
}
Within the "members" array , I want to add Arrays like {id:42,name:Mark} , {id:43,name:Hughes}
Currently i'm adding just ids(eg.42,43). I'm only concerned about the new data as it will have new ids .Please suggest.
Earlier I was using this code to push into the members Array:
$flokkCollection = 'collFlokks';
$flokkCollection->update(
array("_id" => $f_handle),
array('$push' => array("members" => $u_id))
);

Well if what you are asking here is "replacing your existing data" then you need to "loop" the results from the collection and "replace" the array content that exists with your new format.
There are likely smarter ways to approach this, but you are not really giving us all the required information in your question, so I can only answer in the basic terms.
Presuming you have:
$required = array(
array(array("id" => "42"), array("name" => "Mark")),
array(array("id" => "43"), array("name" => "Hughes"))
);
As input, then you do something like this:
function myMapper($v) {
return $v["id"];
}
$mapped = array_map("myMapper",$required);
foreach( $mapped as $value) {
$filtered = array_values(
array_filter($required,function($k) {
return $k["id"] == $value;
})
)[0];
collection.update(array(
array("members" => $value),
array('$set' => array(
"members.$" => $filtered
))
));
}
Which should use the positional $ operator to find the matched "position" of the array element by the value used in the "query" portion of the update statement, then in the "update" portion of that statement $set that current array index to the new value at the "filtered" content index from the original input array.
Outside of PHP. We call these inner elements "objects" and not "arrays" which is a PHP notation trait. Key/value things are "objects" and "lists" are "arrays".

Related

get child from multidimensional array based on value php

i'm working on a project where i have a structured object like this:
$main_array= [
[
"key"=> "home",
"value":=> "Go Home!"
],
[
"key"=> "business",
"value"=> "Go to Work!"
],
[
"key"=> "other",
"value"=> "Go where you want!"
]
]
i'd like to know if there is a way to retrieve the object based on the "key" parameter.
What i want to do is "extract" the nested array like
$home_array=["key"=> "home","value":=> "Go Home!"]
and so on for "business" and "others".
in javascript, i can use jquery or underscore to get what i want, is there a php method to achieve this, or something to simulate a "where" clause in a multidimensional array/object?
thak you in advance
You can easily convert the array you have to have the 'key' column to be the main index using array_column()...
$main_array= [
[
"key"=> "home",
"value"=> "Go Home!"
],
[
"key"=> "business",
"value"=> "Go to Work!"
],
[
"key"=> "other",
"value"=> "Go where you want!"
]
];
$out = array_column($main_array, null, "key");
print_r($out['business']);
Outputs...
Array
(
[key] => business
[value] => Go to Work!
)
A few possibilities to get a single item matching a specific key:
Iterate the main array and stop when you get to a child that has the proper key:
$object = (function($key) use($main_array) {
foreach ($main_array as $object) {
if ($object['key'] == $key) return $object;
}
})('business');
(This example uses an anonymous function, but you can just use a simple foreach loop and break when you find the key.)
Reindex the main array and look up the child by key:
$indexed = array_column($main_array, null, 'key');
$object = $indexed['business'];
Construct the array using the key as the index to begin with. Using string keys doesn't preclude the array elements being other arrays that can contain multiple values.
$main_array= [
'home' => ["value"=> "Go Home!"],
'business' => ["value"=> "Go to Work!"],
'other' => ["value"=> "Go where you want!"]
];
Methods 2 and 3 require that they key is unique. Method 1 doesn't, but it will just return the first instance it finds.
If you do have multiple instances of a key, you probably want array_filter. This will work more like the "where clause" you referred to.
$key = 'home';
$filtered = array_filter($main_array, function($item) use ($key) {
return $item['key'] == $key;
});
This will return multiple items instead of just one.

Multidimensional array loop with array search

I realize there are a number of questions about multidimensional arrays and foreach loops, and I have spent hours reading through them and trying to get my own loop to work -- without success. If the solution is a duplicate, I'll remove my question (or link to another if that is preferred).
Now, the challenge:
Using an array of returned MYSQL results. The results are from multiple joined tables in an associative array. Now I need to convert it to the multidimensional array I need.
I've got most of it working, but my issue is looping through and adding new items to the right place in the array.
Here's some code:
//example of how array is setup in the way I want, this part works.
foreach($results as $i => $a):
//some other code is here, see below.
$items[$i] = [
"id" => $a['id'],
"itemid" => $a['itemid'],
"name" => $a['name'],
"def" => $a['def'],
"class" => $a['class'],
"timeline" => $a['timeline'],
"files" => [
[0] => [
"id" => $a['fileid'],
"name" => $a['filename'],
"path" => $a['filepath'],
"type" => $a['filetype']
]
],
"tags" => [
[0] => [
"id" => $a['tagid'],
"name" => $a['tagname']
]
]
];
endforeach;
Then I've tried a number of ways to loop through in order to only add to the 'tags' or 'files' if the item 'id' is the same as the last. Here is the current code in my editor, not working:
//inside foreach loop, before above code
if($items[$i-1]['id'] == $a['id']):
//it is the same item, works to here.
if(in_array($a['filename'], $items[$i-1], FALSE)):
//add to files array for last item
$items[$i-1]['files'][] = [
"id" => $a['fileid'],
"name" => $a['filename'],
"path" => $a['filepath'],
"type" => $a['filetype']
];
elseif(in_array($a['tagname'], $items[$i-1], FALSE)):
//add to tags array for last item
$items[$i-1]['tags'][] = [
"id" => $a['tagid'],
"name" => $a['tagname']
];
endif;
else:// else it does the code above
As you can see, my most recent attempt was to use in_array, which I now realize doesn't work on multidimensional arrays. My issue is that I can't figure out how to determine if its a new file or new tag for the same item.
Ultimately, I want an array of 'items' which have multiple 'files' and 'tags.' I'm going to json_encode and use it with JS afterwards.
Any advice on how to get this working or optimize it, would be greatly appreciated.
P.S. As I mentioned above, I know this question has been asked before -- though I wasn't able to get their solutions working for me. I'll remove this question if the solution is a duplicate (as in, it's not really helpful to others). Thank you for any help, it is greatly appreciated!
Don't use "autoincrementing" array indices as they easily get messed up. Use your database id since it's already there:
//example of how array is setup in the way I want, this part works.
foreach($results as $i => $a):
$items[$a['id']] = [ // THIS CHANGED.
"id" => $a['id'],
"itemid" => $a['itemid'],
...
Now, with any further result, you can easily check, if the id is already in your array:
if (isset($items[$a['id']])) {
// We had this id before, just add files/tags to it.
// Check first, if files subarray exists, if not: create it.
if (!isset($items[$a['id']]['files'])) {
$items[$a['id']]['files'] = array();
}
$items[$a['id']]['files'][] = array(...); // add the new file.
// Repeat for tags.
}
If your result could return the same file more than once for an id, you can check if the filename is already in there by using a search function:
$filename = $a['filename'];
if (!searchFilename($filename, $items[$a['id']]['files']) {
// Filename is not in there, yet.
// Add file info.
}
function searchFilename($id, $array) {
foreach ($array as $key => $val) {
if ($val['filename'] === $id) {
return true;
}
}
return false;
}
Same applies to tags in a similar way.
In the end, if you do not want the ids for index of $items, just call:
$items = array_values($items);

PHP array loop and format

I am very new to PHP, learning fast but not fast enough! I am also learning Laravel 5.1.
I am trying to build a HTML select list array from an Eloquent query output, in the correct format for form builder (Form::select).
I have the following call to Eloquent to pull the data:
// Get list of States for address select
$states = State::all()->toArray();
It returns the following array:
array:8 [▼
0 => array:2 [▼
"id" => "1"
"state" => "ACT"
]
1 => array:2 [▼
"id" => "2"
"state" => "NSW"
]
...
];
I want to loop through it and generate the following output:
array = [
'' => 'State', <-- This is the default for the select list
'1' => 'ACT',
'2' => 'NSW',
...
];
I am using Laravel 5.1, so I am using the included array_add() function in my helper.
I call my function like this:
$states = create_select_list($states, 'State');
I next want to format the output so it is ready for the Form::select statement. I have tried the code below (as the final try from a few iterations!) but unsuccessfully.
function create_select_list($data, $default)
{
// Declare array and set up default select item
$container = ['' => $default];
// Loop through data entries and build select list array
foreach($data as list($entry, list($key, $value))) {
$container = array_add($container, $key, $value);
}
// Return the select list array
return $container;
}
All help or suggestions are appreciated!
This answer is not about loop fix. I think previous comment should help you.
Just another idea. You can try use array_map instead foreach for this case.
For example:
$states = ['' => 'State'];
array_map(function($item) use (&$states) {
$states[$item['id']] = $item['state'];
}, State::all()->toArray());
Loop like below:
foreach($data as $key => $keyArr ) {
$container = array_add($container, $keyArr['id'], $keyArr['state']);
}
You don't need to use list() in your foreach loop, instead try:
foreach($data as $key => $value) {
$container = array_add($container, $key, $value);
}
The PHP documentation gives a good overview of what list() actually does.

How to update inner array in MongoDb document

I'm trying to add php array to MongoDB document
{
"_id" : ObjectId("51b043e1d07a4e9e06000004"),
"comments" : {
"count" : 0,
"array" : []
}
}
array:
$array = array(
"user_id" => $comment["user_id"],
"text" => $comment["text"]
);
Using this:
$this->database->Collection->update(array("_id" => new MongoId($comment["object_id"])), array('$push' => $array);
However, it doesn't seem to work and I can't find why. I don't know MongoDb well yet... Thanks
The value of the $push needs to be another PHP array with a key that names the array field to update and a value that's the element to add. So in this case it would be:
$this->database->Collection->update(
array("_id" => new MongoId($comment["object_id"])),
array('$push' => array("comments.array" => $array)));

Transform string from associative array into multidimensional array

I'm storing images links into the database separating them with ,, but I want to transform this string into an array, but I'm not sure how to do it.
So my array looks like this:
$array = array(
"name" => "Daniel",
"urls" => "http:/localhost/img/first.png,http://localhost/img/second.png"
);
So I'd like to have it in the following form:
$array2 = array(
"name" => "Daniel",
"urls" => array("http:/localhost/img/first.png",
"http://localhost/img/second.png" )
);
I haven't been PHP'ing for a while, but for that simple use-case I would use explode.
$array['urls'] = explode(',', $array['urls']);
Uncertain if I interpreted your question correct though?
You can use array_walk_recursive like in the following example.
function url(&$v,$k)
{
if($k=='urls') {
$v = explode(",",$v);
}
}
$array = array(
"name" => "Daniel",
"urls" => "http:/localhost/img/first.png,http://localhost/img/second.png"
);
array_walk_recursive($array,"url");
You can check the output on PHP Sandbox

Categories