I have an 2d array that contains a 'title' and 'url' (both strings) as shown below. Is it possible to check for duplicates in the 'url' and if they exist, delete the corresponding 'title' too?
array
0 =>
array
'title' => string 'China - Wikipedia, the free encyclopedia'
'url' => string 'http://en.wikipedia.org/wiki/China'
1 =>
array
'title' => string 'China'
'url' => string 'http://www.state.gov/r/pa/ei/bgn/18902.htm'
2 =>
array
'title' => string 'China | World news | The Guardian'
'url' => string 'http://www.guardian.co.uk/world/china'
3 =>
array
'title' => string 'China Travel Information and Travel Guide - Lonely Planet'
'url' => string 'http://www.lonelyplanet.com/china'
4 =>
array
'title' => string 'ChinaToday.com'
'url' => string 'http://www.chinatoday.com/'
Try this function it could do the job
function super_unique($array,$key)
{
$temp_array = array();
foreach ($array as &$v) {
if (!isset($temp_array[$v[$key]]))
$temp_array[$v[$key]] =& $v;
}
$array = array_values($temp_array);
return $array;
}
$yourearray = super_unique($arr,'url');
Or if you are happy with using the last value of the url you could
foreach($array as $subarray) {
$output[$subarray['url']] = $subarray['title'];
}
Try something like this:
$originals = array();
foreach($array as $key => $value) {
if(!isset($originals[$value['url']])) {
$originals[$value['url']] = true;
}
else {
// exists already, delete entry
unset($array[$key]);
}
}
Related
I'm trying to escape values from a multidimensional array for my database class. The code I have currently:
// Function to escape array values
private function esc_sql_arr(array $to_esc) {
$clean_arr = array();
foreach($to_esc as $k => $v) {
if(is_array($to_esc[$k])) {
foreach($to_esc[$k] as $key => $val) {
$k = $this->_mysqli->real_escape_string($k);
$key = $this->_mysqli->real_escape_string($key);
$val = $this->_mysqli->real_escape_string($val);
$clean_arr[$k][$key] = $val;
}
} else {
$k = $this->_mysqli->real_escape_string($k);
$v = $this->_mysqli->real_escape_string($v);
$clean_arr[$k] = $v;
}
}
return $clean_arr;
}
I'm assuming the following input example (it should be 'where', I purposely changed it to test the above method):
$args = array(
"table" => "t'1",
"data" => array(
"c'sf4;(" => 'xdfbxdrf',
'c2' => "'t'est'",
'cs' => 'hey'
),
"whe're" => array(
'test' => 'test1'
)
);
var_dump:
array (size=3)
'table' => string 't\'1' (length=4)
'data' =>
array (size=3)
'c\'sf4;(' => string 'xdfbxdrf' (length=8)
'c2' => string '\'t\'est\'' (length=10)
'cs' => string 'hey' (length=3)
'whe\'re' =>
array (size=1)
'test' => string 'test1' (length=5)
The code works without any issue. However, is this the right way to escape a multidimensional array?
I believe I might not have to use this method since I use prepared statements. Any feedback on using this is welcome.
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.
I have array, for example:
<?php
$array = array(
0 => array(
'subject' => 'Stackoverflow',
'body' => '',
'name' => 'php'
),
1 => array(
'subject' => 'Test',
'body' => 'Wayne',
'name' => ''
),
2 => array(
'subject' => '',
'body' => 'this is ok',
'name' => ''
),
3 => array(
'subject' => 'cnn',
'body' => 'Google',
'name' => 'private'
),
4 => array(
'subject' => 'code',
'body' => '',
'name' => '7777'
)
);
And i would like get subject, body and name for key 2 and if key not exist then this should get from previous and next (separate function) values.
For example if i want get value from 2 key:
function getCurrentOrPrevious(2);
should return:
array(
'subject' => 'Test', //from [1]
'body' => 'this is ok', //from [2] - current and exist
'name' => 'php' //from [0] - in from [2] and [1] not exist
)
function getCurrentOrNext(2);
should return:
array(
'subject' => 'cnn', //from [3]
'body' => 'this is ok', //from [2] - current
'name' => 'php' //from [3]
)
How is the best way for this? Are there any functions in PHP for such operations?
LIVE
Assuming, you fill your array similar to $array[] = $value; [i.e. that you have consecutive numeric keys starting from zero]:
## $array is the array to take values from, $key is the target key
## $fields are required fields
function getCurrentOrPrevious($array, $key, $fields) {
if ($key < 0) return null;
$output = array();
foreach ($fields as $field) {
for ($i = $key; $i >= 0; $i--) {
if (!empty($array[$i][$field])) {
$output[$field] = $array[$i][$field];
break;
}
}
return $output;
}
Use as follows:
$my_values = getCurrentOrPrevious($array, 12, array('subject', 'body', 'name'));
I guess you could use empty() function of php to check. Also you should think about how far that function shell go?
What if [3] (next) also has an empty value at the same position
What if previous index is <0?
UPDATE
function getCurrOrNext($array, $index){
$keys = array_keys($array[$index]);
foreach($keys AS $key){
if($array[$index][$key] == "") {
$array[$index][$key] = (!empty($array[$index+1]) && !empty($array[$index+1][$key])?$array[$index+1][$key]:null);
}
}
return $array;
}
I guess something like this
function getCurrentOrPrev($array, $key) {
while(key($array)!==$key) next($array); //move internal pointer to required position first
$result = current($array);
//loop is going to execute as long as at least one of elements is empty and we didn't get to beginning of array yet
while((empty($result['subject'])
|| empty($result['body'])
|| empty($result['name']))
&& prev($array)!==false) {
$c = current($array);
//replace empty elements with values of current element
$result['subject'] = empty($result['subject']) ? $c['subject'] : '';
$result['body'] = empty($result['body']) ? $c['body'] : '';
$result['name'] = empty($result['name']) ? $c['name'] : '';
}
return $result;
}
For function with next simply replace prev() method with next(), or to minimize code duplication You may introduce third parameter and call correct method based on its value.
This method doesn't care about values of the key other but the key specified in parameter.
You may have mixed literal and numeric indexes.
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);
}
How can I check if the values are unique in an array based on the key value? Below is the out put of the array. I want to remove duplicate values based on the "id" key. If you check below, the 2nd & 3rd array are same except for the "role" value. Because of this, array_unique is not working on this array.
array
0 =>
array
'id' => string '1521422' (length=7)
'name' => string 'David Alvarado' (length=14)
'role' => string 'associate producer ' (length=20)
1 =>
array
'id' => string '0098210' (length=7)
'name' => string 'Cristian Bostanescu' (length=19)
'role' => string 'line producer: Romania (as Cristi Bostanescu)' (length=46)
2 =>
array
'id' => string '1266015' (length=7)
'name' => string 'Bruno Hoefler' (length=13)
'role' => string 'co-producer ' (length=13)
3 =>
array
'id' => string '1266015' (length=7)
'name' => string 'Bruno Hoefler' (length=13)
'role' => string 'executive producer ' (length=20)
4 =>
array
'id' => string '1672379' (length=7)
'name' => string 'Alwyn Kushner' (length=13)
'role' => string 'associate producer ' (length=20)
Try this one:
<?php
$array = array(
array('id' => 1, 'text' => 'a'),
array('id' => 2, 'text' => 'b'),
array('id' => 1, 'text' => 'c'),
array('id' => 3, 'text' => 'd')
);
$array = array_filter($array, function ($item) {
static $found = array();
if (isset($found[$item['id']])) return false;
$found[$item['id']] = true;
return true;
});
var_dump($array);
This works as of PHP 5.3 (because of the closure and static statement).
cf. http://php.net/manual/en/function.array-filter.php for more information. I tested the statement within loops, it works there as well.
Basically you want to implement a variation of array_unique that does what you want:
function array_unique_multi($arr,$key='id') {
// $arr is the array to work on
// $key is the key to make unique by
$ret = Array();
foreach($arr as $v) {
if( !isset($ret[$v[$key]])) $ret[$v[$key]] = $k;
}
return array_values($ret);
}
You can use this code:
// assuming $arr is your original array
$narr = array();
foreach($arr as $key => $value) {
//$narr[json_encode($value)] = $key;
if (!array_key_exists($value["id"], $narr))
$narr[$value["id"]] = $key;
}
$narr = array_flip($narr);
foreach($arr as $key => $value) {
if (!array_key_exists($key, $narr))
unset($arr[$key]);
}
print_r($arr); // will have no duplicates