How to get the key of a requested item in an array? - php

This is the method I use to find the key of a requested item in an array,
$items = array
(
'0' => array
(
'mnu_id' => '1',
'pg_url' => 'home'
),
'1' => array
(
'mnu_id' => '5',
'pg_url' => 'about'
),
'2' => array
(
'mnu_id' => '6',
'pg_url' => 'venues'
)
);
So if I request the value of 'venues',
while ($current = current($items))
{
if ($current['pg_url'] == 'venues') {
$current_key = key($items);
}
next($items);
}
echo $current_key;
I get the key which is 2.
I don't really like this method as it is a bit lengthy and it confuses me when using while() to loop the array. I don't understand why I have to use next() in the code too!
I wonder if there are any better method than this to get the key?

foreach (array_keys($items) as $key) {
if ($items[$key]['pg_url'] == 'venues') {
$current_key = $key;
// optionally use a break here to escape the loop
}
}

Maybe this is a little easier to understand:
$current_key = -1;
foreach($items as $key => $item) {
if($item['pg_url'] == 'venues') {
$current_key = $key;
}
}
I don't know, what exactly you are trying to do, but it seems like you want to retrieve information from the array depending on the pg_url... if so, maybe it would be nicer to set the pg_url as key:
$items = array
(
'home' => array
(
'mnu_id' => '1'
),
'about' => array
(
'mnu_id' => '5'
),
'venues' => array
(
'mnu_id' => '6'
)
);
then you could simply check for
if(isset($items['venues'])) ...

Related

How to check if duplicate values of some indexes exist in multi dimensional array or not?

My problem is i have a multidimensional array posting from form to php, now i want to checking if duplicate values of some indexes exist in multi dimensional array or not?
e.g:
$data=Array
(
0 => Array
(
uid => '100',
name => 'Sandra Shush',
type => 'abc'
),
1 => Array
(
uid => '101',
name => 'Sandra Shushtext',
type => 'xyz'
),
2 => Array
(
uid => '100',
name => 'Sandra Shush',
type => 'abc'
)
);
here name and type of index 1 and 2 are same, so how can i check it?
I am familiar with
$key = array_search('abc', array_column($data, 'type'));
but it is for duplication of single column value in multi rows, in my situation if multi column of same rows same with multi column of any other row then record will be consider as duplicate.
Any help should be appreciated, Thanks in advance.
You can try using array_reduce by creating a key using your desired item keys:
$result = array_reduce($data, function ($carry, $item) {
$key = $item['uid'] . $item['type'];
$item['is_duplicate'] = isset($carry[$key]);
if ($item['is_duplicate']) {
$carry[] = $item;
} else {
$carry[$key] = $item;
}
return $carry;
}, []);
var_dump($result);
The easiest way, well at least the one I would use is to encode your arrays into md5 (or any other kind) string and compare those values. I think it is the most efficient in your case.
Example:
<?php
function arrayToString($array) {
$str = '';
if ( !is_array($array) )
return $str;
foreach ( $array as $key => $val ) {
$str .= $key . ':' . $val;
}
return $str;
}
$data=Array
(
0 => Array
(
'uid' => '100',
'name' => 'Sandra Shush',
'type' => 'abc'
),
1 => Array
(
'uid' => '100',
'name' => 'Sandra Shush',
'type' => 'xyz'
),
2 => Array
(
'uid' => '100',
'name' => 'Sandra Shush',
'type' => 'abc'
)
);
$temp = array();
foreach ( $data as $d ) {
array_push($temp, md5(arrayToString($d)));
}
$unique = array_unique($temp);
var_dump($unique); // prints unique array
This is a very fast designed approach and will find duplicates. Note that duplicates are elements which have the same value for the same key. So if any of uid, name or type match, they will be treated as duplicates. Therefore I adjust the third array element, because all elements in your array share the same values.
$data = [
....
2 =>
[
'uid' => '200',
'name' => 'Mandra Shush',
'type' => 'abcx'
]
];
$duplicates = [];
$valuesToCompare = ["uid", "name", "type"];
function equals($value, $toCompare, $keysToCompare)
{
foreach ($keysToCompare as $compareKey) {
if ($value[$compareKey] === $toCompare[$compareKey]) {
return true;
}
}
return false;
}
foreach ($data as $index => $element) {
foreach ($data as $indexInner => $elementToCompare) {
if ($index !== $indexInner) {
if (equals($element, $elementToCompare, $valuesToCompare)) {
$duplicates[] = [$index => $indexInner];
}
}
}
}
var_dump($duplicates);
This will output the following, which indicates we found 2 duplicates. Where element 0 is duplicate of 1, and 1 is duplicate of 0.
array (size=2)
0 =>
array (size=1)
0 => int 1
1 =>
array (size=1)
1 => int 0
I achieved above scenario like this:
Dont know which one is best mine or other's who posted answers.
foreach($data as $key => $row)
{
$combinedarr[] = array("name"=>$row["name"],"type"=>$row["type"]);
}
//chck if same facilitiy is being visit on same date twice
$countcomb = count($combinedarr);
$uniquearr = array_unique($combinedarr, SORT_REGULAR);
if($countcomb==count($uniquearr)){
}else{
//yes duplicate exists
};
Thanks again for those who answered.

unable to delete array key from multidimensional array in cakephp

I want to delete array index which contain rating 0 here is my array
array(
(int) 0 => array(
'Gig' => array(
'id' => '1',
'rating' => (int) 5
)
),
(int) 1 => array(
'Gig' => array(
'id' => '3',
'rating' => (int) 9
)
),
(int) 2 => array(
'Gig' => array(
'id' => '4',
'rating' => '0'
)
)
)
and what I did
for($i = 0; $i<count($agetGigsItem); $i++)
{
if($agetGigsItem[$i]['Gig']['rating']==0)
{
unset($agetGigsItem[$i]);
}
$this->set('agetGigsItem', $agetGigsItem);
}
i also try foreach loop but unable to resolve this issue.
foreach ($agetGigsItem as $key => $value) {
if ($value["Gig"]["rating"] == 0) { unset($agetGigsItem[$key]); }
}
I think you need to reupdate your array.
foreach ($agetGigsItem as $key => $value) {
if ($value["Gig"]["rating"] != 0)
{
unset($agetGigsItem[$key]);
}
$this->set('agetGigsItem', $agetGigsItem);
}
I hope you are missing $this and so you cannot access the array in CakePHP.
So try this:
foreach ($this->$agetGigsItem as $key => $value) {
if ($value["Gig"]["rating"] == 0) {
unset($this->$agetGigsItem[$key]);
}
}
This code will unset arrey index with value 0.
<?php
$array=array(
array(
'Gig' => array(
'id' => '1',
'rating' =>5
)
),
array(
'Gig' => array(
'id' => '3',
'rating' =>9
)
),
array(
'Gig' => array(
'id' => '4',
'rating' =>0
)
)
);
foreach($array as $a){
if($a['Gig']['rating']==0){
unset($a['Gig']['rating']);
}
$array1[]=$a;
}
var_dump($array1);
Destroying occurances within an array you are actually processing over with a for or a foreach is always a bad idea. Each time you destroy an occurance the loop can easily get corrupted and get in a terrible mess.
If you want to remove items from an array it is better to create a copy of the array and process over that new array in the loop but remove the items from the original array.
So try this instead
$tmparray = $this->agetGigsItem; // will copy agetGigsItem into new array
foreach ($tmparray as $key => $value) {
if ($value["Gig"]["rating"] == 0) {
unset($this->agetGigsItem[$key]);
}
}
unset($tmparray);

Laravel/PHP create an array from array

Hey guys I'm confused about how to create an array using specific keys from my pre-existing array.
Laravel controller
public function index()
{
$content = Page::find(1)->content->toArray();
return View::make('frontend.services', compact('content'));
}
$content is an array that looks similar to
array (
0 => array (
'id' => '1',
'page_id' => '1',
'name' => 'banner_heading',
'content' => 'some content', ),
1 => array (
'id' => '2',
'page_id' => '1',
'name' => 'banner_text',
'content' => 'some other content' )
)
And I want it recreate this array to look like this
array (
0 => array (
'banner_heading' => 'some content'
),
1 => array (
'banner_text' => 'some other content'
)
)
How can I move the keys name and content to equal their values as a single row in the array?
I greatly appreciate any advice.
PHP >= 5.5.0:
$result = array_column($content, 'content', 'name');
PHP < 5.5.0:
foreach($content as $key => $array) {
$result[$key] = array($array['name'] => $array['content']);
}
You mean
$newContent = array();
foreach ($content as $record) {
$newContent[] = array($record['name'] => $record['content']);
}
?
I don't know Laravel, but i believe that your solutions should be similar to this :
$newArray= array();
foreach($content as $key => $value)
{
$newArray[] = $value["banner_heading"];
}
return View::make('frontend.services', compact('newArray'));
Or at least it should be something similar with this.

Get key of multidimensional array?

For example, I have multidimensional array as below:
$array = array (
0 =>
array (
'id' => '9',
'gallery_id' => '2',
'picture' => '56475832.jpg'
),
1 =>
array (
'id' => '8',
'gallery_id' => '2',
'picture' => '20083622.jpg'
),
2 =>
array (
'id' => '7',
'gallery_id' => '2',
'picture' => '89001465.jpg'
),
3 =>
array (
'id' => '6',
'gallery_id' => '2',
'picture' => '47360232.jpg'
),
4 =>
array (
'id' => '5',
'gallery_id' => '2',
'picture' => '4876713.jpg'
),
5 =>
array (
'id' => '4',
'gallery_id' => '2',
'picture' => '5447392.jpg'
),
6 =>
array (
'id' => '3',
'gallery_id' => '2',
'picture' => '95117187.jpg'
)
);
How can I get key of array(0,1,2,3,4,5,6)?
I have tried a lot of examples, but nothing has worked for me.
This is quite simple, you just need to use array_keys():
$keys = array_keys($array);
See it working
EDIT For your search task, this function should do the job:
function array_search_inner ($array, $attr, $val, $strict = FALSE) {
// Error is input array is not an array
if (!is_array($array)) return FALSE;
// Loop the array
foreach ($array as $key => $inner) {
// Error if inner item is not an array (you may want to remove this line)
if (!is_array($inner)) return FALSE;
// Skip entries where search key is not present
if (!isset($inner[$attr])) continue;
if ($strict) {
// Strict typing
if ($inner[$attr] === $val) return $key;
} else {
// Loose typing
if ($inner[$attr] == $val) return $key;
}
}
// We didn't find it
return NULL;
}
// Example usage
$key = array_search_inner($array, 'id', 9);
The fourth parameter $strict, if TRUE, will use strict type comparisons. So 9 will not work, you would have to pass '9', since the values are stored as strings. Returns the key of the first occurence of a match, NULL if the value is not found, or FALSE on error. make sure to use a strict comparison on the return value, since 0, NULL and FALSE are all possible return values and they will all evaluate to 0 if using loose integer comparisons.
Try this , I think it will help you.
foreach ($array as $key=>$value)
{
echo $key.'<br/>';
echo $value['id'].'<br/>';
echo $value['gallery_id'].'<br/>';
echo $value['picture'].'<br/><br/>';
}
sometimes it is to easy to find ;)
array_keys($array);
array_keys
Probably http://php.net/manual/en/function.array-keys.php ?
Convert your double dimensional array on your own:
$tmp = null
foreach($array as $key => $value) {
$tmp[] = $key;
}
print_r($tmp);
You mean something like this:
function getKeys($array)
{
$resultArr = array();
foreach($array as $subArr) {
$resultArr = array_merge($resultArr, $subArr);
}
return array_keys($resultArr);
}

Matching an array value by key in PHP

I have an array of items:
array(
[0] => array(
'item_no' => 1
'item_name' => 'foo
)
[1] => array(
'item_no' => 2
'item_name' => 'bar'
)
) etc. etc.
I am getting another array from a third party source and need to remove items that are not in my first array.
array(
[0] => array(
'item_no' => 1
)
[1] => array(
'item_no' => 100
) # should be removed as not in 1st array
How would I search the first array using each item in the second array like (in pseudo code):
if 'item_no' == x is in 1st array continue else remove it from 2nd array.
// Returns the item_no of an element
function get_item_no($arr) { return $arr['item_no']; }
// Arrays of the form "item_no => position in the array"
$myKeys = array_flip(array_map('get_item_no', $myArray));
$theirKeys = array_flip(array_map('get_item_no', $theirArray));
// the part of $theirKeys that has an item_no that's also in $myKeys
$validKeys = array_key_intersect($theirKeys, $myKeys);
// Array of the form "position in the array => item_no"
$validPos = array_flip($validKeys);
// The part of $theirArray that matches the positions in $validPos
$keptData = array_key_intersect($theirArray, $validPos);
// Reindex the remaining values from 0 to count() - 1
return array_values($keptData);
All of this would be easier if, instead of storing the key in the elements, you stored it as the array key (that is, you'd be using arrays of the form "item_no => item_data") :
// That's all there is to it
return array_key_intersect($theirArray, $myArray);
You can also do:
$my_array =array(
0 => array( 'item_no' => 1,'item_name' => 'foo'),
1 => array( 'item_no' => 2,'item_name' => 'bar')
);
$thrid_party_array = array(
0 => array( 'item_no' => 1),
1 => array( 'item_no' => 100),
);
$temp = array(); // create a temp array to hold just the item_no
foreach($my_array as $key => $val) {
$temp[] = $val['item_no'];
}
// now delete those entries which are not in temp array.
foreach($thrid_party_array as $key => $val) {
if(!in_array($val['item_no'],$temp)) {
unset($thrid_party_array[$key]);
}
}
Working link
If your key is not actually a key of your array but a value, you will probably need to do a linear search:
foreach ($itemsToRemove as $itemToRemove) {
foreach ($availableItems as $key => $availableItem) {
if ($itemToRemove['item_no'] === $availableItem['item_no']) {
unset($availableItems[$key]);
}
}
}
It would certainly be easier if item_no is also the key of the array items like:
$availableItems = array(
123 => array(
'item_no' => 123,
'item_name' => 'foo'
),
456 => array(
'item_no' => 456,
'item_name' => 'bar'
)
);
With this you could use a single foreach and delete the items by their keys:
foreach ($itemsToRemove as $itemToRemove) {
unset($availableItems[$itemToRemove['item_no']]);
}
You could use the following to build an mapping of item_no to your actual array keys:
$map = array();
foreach ($availableItems as $key => $availableItem) {
$map[$availableItems['item_no']] = $key;
}
Then you can use the following to use the mapping to delete the corresponding array item:
foreach ($itemsToRemove as $itemToRemove) {
unset($availableItems[$map[$itemToRemove['item_no']]]);
}

Categories