Remove certain keys and values from associative array - php

I have a array that looks like this:
[['title'= >'my title','time'=>'14:00','date'=>'feb 2'],['title'= >'another','time'=>'14:00','date'=>'feb 2']]
Now I wish to remove all time and date keys from the arrays and also rename the title to text so it looks like this:
[['text'= >'my title'],['text'= >'another title']]
I have tried to use
$tags = array_map(function($tag) {
return array(
'text' => $tag['title'],
);
}, $tags);
But I cant get it to work

Laravel solution:
collect($array)->transform(function($i) { return ['text' => $i['title']]; })->toArray();

You can transform your collections,
$mycollection = $myModel->get();
return $mycollection->map(function($row){
return [
'text' => $row->title,
];
});
Or you can use Fractal: http://fractal.thephpleague.com/transformers/

$newTags = [];
foreach($tags as $tag) {
$newTags[] = [['text'] => $tag['title']];
}
$tags = $newTags;

This question isn't specific to Laravel, but since you mention it:
Use the collect() helper and it's methods for convenience. You'll want to look at pull, map, and maybe transform in particular.
If you don't use it then unset will delete the index you want from the array.
Alternatively, just create a new array:
$a = []
foreach($tags as $tag) {
$a[] = ['text' => $tag['title']];
}
edit: fix

Related

Delete a duplicate string appearing in all array elements

In Laravel I can return data from Google analytics to get most visited page with this command:
$FilterData =$this->parseResults($data)->pluck('url');
It will be return this URLs:
[
"/products/r4-04",
"/products/r6-01",
"/products/cu3-20",
"/products/r4-51",
"/products/zp-1",
"/products/r5-31",
"/products/cu3-64",
"/products/cu6-01-1",
"/products/cu6-01-2",
"/products/r4-14",
"/products/t4-74",
"/products/cu-001",
"/products/cu5-18",
"/products/zp-8",
"/products/td6-01",
"/products/t4-14",
"/products/c6-01"
]
Now I want to remove all /products/ word from this and find the products by slug.
If you need just remove /products/ from every array value, you can use str_replace for this:
$FilterData =$this->parseResults($data)->pluck('url');
$FilterDataNew = str_replace("/products/","",$FilterData);
var_dump($FilterDataNew);
<?php
$products = [
"/products/r4-04",
"/products/r6-01",
"/products/cu3-20",
"/products/r4-51",
"/products/zp-1",
"/products/r5-31",
"/products/cu3-64",
"/products/cu6-01-1",
"/products/cu6-01-2",
"/products/r4-14",
"/products/t4-74",
"/products/cu-001",
"/products/cu5-18",
"/products/zp-8",
"/products/td6-01",
"/products/t4-14",
"/products/c6-01"
];
function replace($product) {
return str_replace('/products/', '', $product);
}
$products = array_map('replace', $products);
You can simple use str_replace to achieve the same.
Assuming your variable as $products
$array = str_replace('/products/', '', $products);
dd($array);

Array_map through a array of objects and grab properties

So I have a var_dump($instagram->get_images()); that gives me the following output:
I want to use array_map to map through all the properties and use them inside a foreach loop later on.. but I'm running into some issues:
Here is the attempt that I have:
$mediaUrls = array_map(function($entry) {
return [
'media_url' => $entry['media_url'],
];
}, $instagram->get_images());
I'm getting back the following error:
Could someone assist me on properly array_mapping through the objects and then later be able to use foreach ($MediaUrls as $media) etc...
The error is correct. You're using array map on an object. But the object does have a ->data property that is an array. But the items in the array are objects, so you'll need to refer to their properties rather than using array syntax.
$images = $instagram->get_images();
$mediaUrls = array_map(function($entry) {
return [
'media_url' => $entry->media_url,
];
}, $images->data);
Couple of suggestions. You said, "I want to use array_map to map through all the properties and use them inside a foreach loop later on."
You can reiterate $images->data later on, so I don't really see the value of making another array just for that purpose
foreach ($images->data as $imageData) {
// do something with $imageData->media_url
}
This would be almost exactly the same as iterating the array you're making with array_map.
foreach ($images->data as $imageData) {
// do something with $imageData['media_url']
}
If you want to get an array of just the urls, you can do it more simply with array_column.
$images = $instagram->get_images();
$mediaUrls = array_column($images->data, 'media_url');
(This won't give you the same result. It will be an array of strings rather than an array of arrays.)

PHP / Extract navigation from Array

I have an XML document and i'm using SimpleXMLElement to parse it with PHP like :
<Document>
<Hello>
<Name>Jason</Name>
</Hello>
</Document>
Example to access to the name loading my XML and then i do :
$xml->Document->Hello->Name
I would like to store all this routes in associative array like
$array = [
"Document->Hello->Name" => "name"
];
The problem is when i loop on this array my field is empty
I do this :
foreach($array as $key => $v)
{
$hereIsempty = $xml->$key
}
Is someone have a solution to get the value i want from my array mapping plz
Storing full route path in one key is a bad idea.
if you know in advance the meaning of the path: set the tags name to const value and then use it.
But if you realy need to save path as key in array, you can separate all tags in first sub-array and set needs value as second element of array; something like this:
$needs = [];
$routes = [
[
'tags' => ['Document', 'Hello'],
'need' => 'Name'
]
];
foreach ($routes as $route) {
tempXml = $xml;
foreach ($route['tags'] as $tag) {
$tempXml = $tempXml->{$tag};
}
$need[] = (string)$tempXml->{$route['need']};
}

Laravel iterate array and write to Model with Relations

I think about dynamic model creation or updating an model.
Let's assume i have an array like this:
$data = array(
'first_name' => 'Max',
'last_name' => 'Power',
'invoiceAddress.city' => 'Berlin',
'invoiceAddress.country_code' => 'DE',
'user.status_code' => 'invited'
);
Now i would like to iterate that array, and write the data to an model, where the dot notation tells me that i must write to an relation.
Normal code:
$model->first_name = $data['first_name'];
$model->last_name = $data['last_name'];
$model->invoiceAddress->city = $data['invoiceAddress.city'];
and so on.
I would prefer a more dynamic way:
foreach($data as $key => $value){
$properties = explode('.',$key);
//Now the difficult part
$model[$properties[0]][$properties[1]] = $value;
//Would work for invoiceAddress.city,
//but not for first_name
}
Here is the problem, that i don't know how many properties the explode will create.
Is there a way to solve such problem in a dynamic way?
You could use the Illuminate\Support\Arr helper from Laravel like this:
foreach($data as $key => $value) {
Arr::set($model, $key, $value);
}
It works because the Arr class uses dot notation to access the properties like:
Arr::get($model, 'invoiceAddress.country_code');
Is equivalent to:
$model['invoiceAddress']['country_code'];
If you prefer to use cleaner helper:
foreach($data as $key => $value) {
array_set($model, $key, $value);
}
You could also use these Laravel helpers data_fill() or data_set().
Other doted notation functions are listed here.

How to extract particular fields from an array [duplicate]

This question already has answers here:
Is there a function to extract a 'column' from an array in PHP?
(15 answers)
Closed 9 months ago.
I have an array that looks
$articles = array([0] => array('title' => 'When ....',
'description' => '....',
'created' => '2011-02-21'
),
[1] => array('title' => 'Something ....',
'description' => 'When ....',
'created' => '2011-02-21'
),
);
I want to extract only the titles. Is there anyway to retrieve the titles without using for and foreach loops. I dont mind the title becomes a single string. I was thinking implode the array but that adds description and created.
considering its CakePHP, $titles = Set::extract('/title', $articles);
edit:
http://book.cakephp.org/view/1487/Set
Update:
With CakePHP 2.x Hash has replaced Set.
$titles = Hash::extract($articles, '{n}.title');
You can use for example array_map, but why do you not want to use Loops? In fact every method, that is able to modify the array in the way you want it, will iterate over it.
function reduce_to_title ($item) {
return $item['title'];
};
$titles = array_map('reduce_to_title', $articles);
Or since PHP>=5.3
$titles = array_map(function ($item) {
return $item['title'];
}, $articles);
you can use this
print_r(array_map('array_shift', $articles));
EDIT :
Assumption : if title is the first element of array.
since 5.5, array_column does exactly what you explained.
$titles = array_column($articles, "title"); // [0=>"When",1=>"Something"]
For more examples check the PHP manual
What about while loops?
reset($articles); while($a = each($articles)){echo $a['value']['title'];}
an improved version of KingCrunch's answer:
function get_column(&$array,$column) {
foreach ($array as $value) {
$ret[]=$value[$column];
}
return $ret;
}
this is pretty universal function and can be put into some library, and then called with just single line, which is shorter than in every other answer:
$titles = get_column($articles, 'title');
Update
However, it seems that cake already have such a function, so, the only proper answer is
How to extract particular fields from an array
Hey, since you're using CakePHP, why don't you just add title to the fields array in your find()? For example, the following,
$this->Article-find('all', array('fields'=>'Article.title'));
will pull only the titles of all matching Articles in the database.

Categories