I have array such as:
$arr = [
0=>['note_id'=>1,'content'=>1],
1=>['note_id'=>2,'content'=>2],
2=>['note_id'=>3,'content'=>3],
];
And I have array of ids:
$ids=[2,3,1];
I need get new array from arr by using the sorting this array by value 'note_id' and array ids, so resut must be:
$arr = [
1=>['note_id'=>2,'content'=>2],
2=>['note_id'=>3,'content'=>3],
0=>['note_id'=>1,'content'=>1],
];
Are there any functions for this? Thanks!
You could loop both the arrays and compare the keys of $arr with with the values of $ids and create your new array $newArr.
$arr = [
0 => ['note_id' => 1, 'content' => 1],
1 => ['note_id' => 2, 'content' => 2],
2 => ['note_id' => 3, 'content' => 3],
];
$ids = [2, 3, 1];
$newArr = [];
foreach ($ids as $id) {
foreach ($arr as $keyArr => $item) {
if ($id === $item['note_id']) {
$newArr[$keyArr] = $item;
}
}
}
print_r($newArr);
Result:
Array
(
[1] => Array
(
[note_id] => 2
[content] => 2
)
[2] => Array
(
[note_id] => 3
[content] => 3
)
[0] => Array
(
[note_id] => 1
[content] => 1
)
)
Demo
Related
i have data array, and this my array
Array
(
[0] => Array
(
[id] => 9,5
[item] => Item A, Item B
)
[1] => Array
(
[id] => 3
[item] => Item C
)
)
in array 0 there are two ID which I separated using a comma, I want to extract the data into a new array, how to solve this?
so the output is like this
Array
(
[0] => Array
(
[id] => 9
[item] => Item A
)
[1] => Array
(
[id] => 3
[item] => Item C
)
[2] => Array //new array
(
[id] => 5
[item] => Item B
)
)
this my code
$arr=array();
foreach($myarray as $val){
$arr[] = array(
'id' => $val['id'],
'item' => $val['item'],
);
}
echo '<pre>', print_r($arr);
$arr = [
array(
'id' => '9,5',
'item' => 'Item A, Item B'
),
array(
'id' => 3,
'item' => 'Item C'
)
];
$newArr = array_reduce($arr, function($tmp, $ele){
$arrIds = explode(',', $ele['id']);
$arrItems = explode(',', $ele['item']);
forEach($arrIds as $key => $arrId) {
$tmp[] = array('id' => $arrId, 'item' => $arrItems[$key]);
}
return $tmp;
});
The code down below should do the job. But I didn't understand why you didn't create those items seperately in the first place.
foreach ($arr as $i => $data) {
if (!str_contains($data['id'], ',')) continue;
$items = explode(',', $data['item']);
foreach(explode(',', $data['id']) as $i => $id) {
$new = ['id' => $ids[$i], 'item' => $items[$i]];
if ($i) $arr[] = $new;
else $arr[$i] = $new;
}
}
There's a following array:
$input = [
'adults' => [1, 2],
'children' => [3, 4]
];
The number of keys and values might be dynamic in this array (but the structure, key => Numeric:Array always remains the same).
I want to turn this array into the following structure:
[
[
'adults' => 1,
'children' => 3
],
[
'adults' => 2,
'children' => 4
]
]
In order to achieve this, I wrote the following function:
function parse(array $input)
{
$output = [];
$keys = array_keys($input);
foreach ($input as $parameter => $values) {
$internal = [];
foreach ($values as $value) {
foreach ($keys as $key) {
if (!isset($internal[$key])) {
$internal[$key] = $value;
}
}
}
$output[] = $internal;
}
return $output;
}
But this gives an unxpected output:
print_r(parse($input));
Array
(
[0] => Array
(
[adults] => 1
[children] => 1
)
[1] => Array
(
[adults] => 3
[children] => 3
)
)
Somehow the values always get overriden by the last one inside the parsing function. So what might cause this error?
If I understand the logic correctly, this should work:
function parse(array $input)
{
$output = [];
foreach ($input as $key1 => $values) {
foreach ($values as $key2 => $value) {
$output[$key2][$key1] = $value;
}
}
return $output;
}
https://3v4l.org/HeXUp
With a larger array
$input = [
'adults' => [1, 2],
'children' => [3, 4],
'foo' => [2, 7],
'bar' => [4, 6],
];
This returns
Array
(
[0] => Array
(
[adults] => 1
[children] => 3
[foo] => 2
[bar] => 4
)
[1] => Array
(
[adults] => 2
[children] => 4
[foo] => 7
[bar] => 6
)
)
I have an array with the following structure:
[0] => Array
(
[venue1] => 1
[venue2] => 2
)
[1] => Array
(
[venue1] => 3
[venue2] => 4
)
[2] => Array
(
[venue1] => 2
[venue2] => 1
)
[3] => Array
(
[venue1] => 5
[venue2] => 6
)
I need to remove the duplicate "pair of values", in this case row [0] and row [2]
I tried it with that code, but it doesn't work (and of course it's not very elegant) ;-)
foreach ( $compare_arr as $v1 )
{
$key = array_search( intval($v1[venue1]), array_column( $compare_arr, 'venue2' ) );
if ( $key <> '' ) unset($compare_arr[$key]);
}
Do you have an idea how to solve this?
Thanks a lot for your help!
Oliver
Here is an approach where an intermediate array is formed of sorted values. That you can then search for to find duplicate pairs to remove.
<?php
$venues =
array (
0 =>
array (
'venue1' => 1,
'venue2' => 2,
),
1 =>
array (
'venue1' => 3,
'venue2' => 4,
),
2 =>
array (
'venue1' => 2,
'venue2' => 1,
),
3 =>
array (
'venue1' => 5,
'venue2' => 6,
),
);
$result = $pairs = $venues;
array_walk($pairs, 'sort');
var_export($pairs);
foreach($pairs as $k => $pair) {
if(count(array_keys($pairs, $pair)) > 1) {
unset($result[$k]);
}
}
var_export($result);
Output:
array (
0 =>
array (
0 => 1,
1 => 2,
),
1 =>
array (
0 => 3,
1 => 4,
),
2 =>
array (
0 => 1,
1 => 2,
),
3 =>
array (
0 => 5,
1 => 6,
),
)array (
1 =>
array (
'venue1' => 3,
'venue2' => 4,
),
3 =>
array (
'venue1' => 5,
'venue2' => 6,
),
)
If you want to remove occurring duplicates rather than pruning out duplicates altogether, you can do an array_unique on the sorted array above and then use the remaining keys to filter the original array.
$tmp = $venues;
array_walk($tmp, 'sort');
$tmp = array_unique($tmp, SORT_REGULAR);
$result = array_intersect_key($venues, $tmp);
var_export($result);
Output:
array (
0 =>
array (
'venue1' => 1,
'venue2' => 2,
),
1 =>
array (
'venue1' => 3,
'venue2' => 4,
),
3 =>
array (
'venue1' => 5,
'venue2' => 6,
),
)
You might also first loop the array creating a compound key based on the ordered keys.
Then you can filter the result only keeping arrays where the count is 2 as nothing is added because there are no duplicates.
For example
$result = [];
$compare_arr = [
["venue1" => 1, "venue2" => 2],
["venue1" => 3, "venue2" => 4],
["venue1" => 2, "venue2" => 1],
["venue1" => 5, "venue2" => 6],
];
foreach ($compare_arr as $v1) {
sort($v1);
$cKey = $v1[0] .'-'. $v1[1];
if (array_key_exists($cKey, $result)) {
$result[$cKey][] = $v1;
continue;
}
$result[$cKey] = $v1;
}
$result = array_filter($result, function($item) {
return count($item) === 2;
});
print_r($result);
Output
Array
(
[3-4] => Array
(
[0] => 3
[1] => 4
)
[5-6] => Array
(
[0] => 5
[1] => 6
)
)
You can see the compound keys are the values with a - in between. If you want to have the keys numbered from 0, you can use array_values.
Php demo
Edit
If you want to keep the first matching single pair, you can check for the compound key and if it already exists continue the loop without overwriting the existing one.
$result = [];
$compare_arr = [
["venue1" => 1, "venue2" => 2],
["venue1" => 3, "venue2" => 4],
["venue1" => 2, "venue2" => 1],
["venue1" => 5, "venue2" => 6]
];
foreach ($compare_arr as $v1) {
sort($v1);
$cKey = $v1[0] .'-'. $v1[1];
if (array_key_exists($cKey, $result)) {
continue;
}
$result[$cKey] = $v1;
}
print_r($result);
Output
Array
(
[1-2] => Array
(
[0] => 1
[1] => 2
)
[3-4] => Array
(
[0] => 3
[1] => 4
)
[5-6] => Array
(
[0] => 5
[1] => 6
)
)
Php demo
Whether you use a classic foreach() loop or functional iteration, there is no reason to iterate the input array more than once.
This snippet will appear nearly identical to TheFourthBird's answer, but I don't like the unnecessary use of continue. This snippet will ensure no that rows in the result array have 100% shared venue values (in any order). The subarray keys will also not suffer reordering; in other words the first element key will be venue1 then the second element will be venue2. Using implode() offers additional flexibility because the code won't need to be altered if the number of elements in each row changes.
$result = [];
foreach ($data as $index => $row) {
sort($row);
$key = implode('-', $row);
if (!isset($result[$key])) {
$result[$key] = $data[$index];
}
}
var_export(array_values($result));
Output:
array (
0 =>
array (
'venue1' => 1,
'venue2' => 2,
),
1 =>
array (
'venue1' => 3,
'venue2' => 4,
),
2 =>
array (
'venue1' => 5,
'venue2' => 6,
),
)
To completely remove all rows where venue values are shared, maintain a "found" array as well as a "result" array.
Code: (Demo)
$result = [];
foreach ($data as $index => $row) {
sort($row);
$key = implode('-', $row);
if (!isset($found[$key])) {
$found[$key] = true;
$result[$key] = $data[$index];
} else {
unset($result[$key]);
}
}
var_export(array_values($result));
Output:
array (
0 =>
array (
'venue1' => 3,
'venue2' => 4,
),
1 =>
array (
'venue1' => 5,
'venue2' => 6,
),
)
for example, I have a array:
$objects = ['car', 'cat', 'dog', 'Peter'];
and another:
$types = [
'man' => ['Peter', 'John','...'],
'animal' => ['pig', 'cat', 'dog', '...'],
'vehicle' => ['bus', 'car', '...']
];
and my goal is get an array like:
$result = [
'man' => ['Peter'],
'animal' => ['cat', 'dog'],
'vehicle' => ['car']
]
what is the most efficient way to search within an array, in my current work, I use two foreach loop to search but figured it's too slow, I have about thousands of elements in my array.
Use array_intersect:
foreach ($types as $key => $type) {
$result[$key] = array_intersect($type, $objects);
}
$objects = ['car', 'cat', 'dog', 'Peter'];
$types = [
'man' => ['Peter', 'John'],
'animal' => ['pig', 'cat', 'dog'],
'vehicle' => ['bus', 'car']
];
foreach ($types as $key => $type) {
$result[$key] = array_intersect($type, $objects);
}
echo '<pre>';
print_r($result);
Array
(
[man] => Array
(
[0] => Peter
)
[animal] => Array
(
[1] => cat
[2] => dog
)
[vehicle] => Array
(
[1] => car
)
)
I have an array as such:
[0] => Array
(
[0] => 1
[1] => 30
[2] => 33
)
[1] => Array
(
[id] => 5
)
I want to move all values in the [0] index out so they become part of the parent array. So the final outcome would look like such:
[0] => Array
(
[id] => 1
)
[1] => Array
(
[id] => 30
)
[2] => Array
(
[id] => 33
)
[3] => Array
(
[id] => 5
)
As you can see the numerical indexes on [0] have now changed to id
I've tried using array_map('current', $array[0])
to no avail, any suggestions?
You could use the ol' trusty double foreach:
$new_array = array();
foreach ($array as $arr) {
foreach ($arr as $ar) {
$new_array[] = array('id'=>$ar);
}
}
Demo
$data = array(
array(1, 30, 33),
array('id' => 5)
);
$result = array();
array_walk_recursive(
$data,
function($value) use (&$result) {
$result[] = array('id' => $value);
}
);
var_dump($result);
Just to show that iterators can be really useful tools as well:
$data = array(
array(1, 30, 33),
array('id' => 5)
);
$result = array();
foreach (new RecursiveIteratorIterator(
new RecursiveArrayIterator($data),
RecursiveIteratorIterator::LEAVES_ONLY
) as $value) {
$result[] = array('id' => $value);
}
var_dump($result);
$array = [
[1, 30, 33],
['id' => 5]
];
$result = array_reduce($array, function (array $result, array $array) {
return array_merge($result, array_map(
function ($id) { return compact('id'); },
array_values($array)
));
}, []);
var_dump($result);
Admittedly not the simplest way to solve this, but very "functional". ;)
$array = array(
array(0 => 1,1 => 30,2 => 33,),
array("id" => 5,)
);
$result = array_merge(
array_map('array_flip',
array_chunk(
array_fill_keys($array[0], "id"),
1, true)
),
array_slice($array, 1)
);
var_export($result);
Results in:
array (
array ( 'id' => 1 ),
array ( 'id' => 30 ),
array ( 'id' => 33 ),
array ( 'id' => 5 )
)