reaarange array after deleting its element - php

hi
i have array like $arr with 10 elements when i unset the 5 element and print the array it print he array without 5 indx. now i want to rearrange the array with 9 elements and first four values index will be same but after this values should be shifted to (previous index-1).
is there any simple method is there (array function). or i have to made a complete logic for this.

Well, if you want to maintain order, but just want to re-index the keys, you can use the array_values() function.
$a = array(
0 => 'a',
1 => 'b',
2 => 'c',
3 => 'd'
);
unset($a[1]);
$a = array(
0 => 'a',
2 => 'c',
3 => 'd'
); // Note, this is what $a is now, the re-assignment is for illustration only
$a = array_values($a);
$a = array(
0 => 'a',
1 => 'c',
2 => 'd'
); // Note, this is what $a is now, the re-assignment is for illustration only

You should use array_splice, rather than unset, to remove the elements from the array. Doing so will reorder the remaining elements:
$input = array("red", "green", "blue", "yellow");
array_splice($input, 1, 1);
// $input is now array("red", "blue", "yellow")

Not too sure if there's a better way but you can use array_reverse(), twice:
$array = array_reverse($array, false);
$array = array_reverse($array, false);

Related

how to fix array_udiff while having strings inside array [duplicate]

I have an array containing rows of associative data.
$array1 = array(
array('ITEM' => 1),
array('ITEM' => 2),
array('ITEM' => 3),
);
I have a second array, also containing rows of associative data, that I would like to filter using the first array.
$array2 = array(
array('ITEM' => 2),
array('ITEM' => 3),
array('ITEM' => 1),
array('ITEM' => 4),
);
This feels like a job for array_diff(), but how can I compare the rows exclusively on the deeper ITEM values?
How can I filter the second array and get the following result?
array(3 => array('ITEM' => 4))
You can define a custom comparison function using array_udiff().
function udiffCompare($a, $b)
{
return $a['ITEM'] - $b['ITEM'];
}
$arrdiff = array_udiff($arr2, $arr1, 'udiffCompare');
print_r($arrdiff);
Output:
Array
(
[3] => Array
(
[ITEM] => 4
)
)
This uses and preserves the arrays' existing structure, which I assume you want.
I would probably iterate through the original arrays and make them 1-dimensional... something like
foreach($array1 as $aV){
$aTmp1[] = $aV['ITEM'];
}
foreach($array2 as $aV){
$aTmp2[] = $aV['ITEM'];
}
$new_array = array_diff($aTmp1,$aTmp2);
Another fun approach with a json_encode trick (can be usefull if you need to "raw" compare some complex values in the first level array) :
// Compare all values by a json_encode
$diff = array_diff(array_map('json_encode', $array1), array_map('json_encode', $array2));
// Json decode the result
$diff = array_map('json_decode', $diff);
A couple of solutions using array_filter that are less performant than the array_udiff solution for large arrays, but which are a little more straightforward and more flexible:
$array1 = [
['ITEM' => 1],
['ITEM' => 2],
['ITEM' => 3],
];
$array2 = [
['ITEM' => 2],
['ITEM' => 3],
['ITEM' => 1],
['ITEM' => 4],
];
$arrayDiff = array_filter($array2, function ($element) use ($array1) {
return !in_array($element, $array1);
});
// OR
$arrayDiff = array_filter($array2, function ($array2Element) use ($array1) {
foreach ($array1 as $array1Element) {
if ($array1Element['ITEM'] == $array2Element['ITEM']) {
return false;
}
}
return true;
});
As always with array_filter, note that array_filter preserves the keys of the original array, so if you want $arrayDiff to be zero-indexed, do $arrayDiff = array_values($arrayDiff); after the array_filter call.
you can use below code to get difference
$a1 = Array(
[0] => Array(
[ITEM] => 1
)
[1] => Array(
[ITEM] => 2
)
[2] => Array(
[ITEM] => 3
)
);
$a2 = Array(
[0] => Array(
[ITEM] => 2
)
[1] => Array(
[ITEM] => 3
)
[2] => Array(
[ITEM] => 1
)
[3] => Array(
[ITEM] => 4
));
array_diff(array_column($a1, 'ITEM'), array_column($a2, 'ITEM'));
Having the same problem but my multidimensional array has various keys unlike your "ITEM" consistently in every array.
Solved it with: $result = array_diff_assoc($array2, $array1);
Reference: PHP: array_diff_assoc
Another solution
if( json_encode($array1) == json_encode($array2) ){
...
}
Trust that the maintainers of PHP have optimized array_udiff() to outperform all other techniques which could do the same.
With respect to your scenario, you are seeking a filtering array_diff() that evaluates data within the first level's "value" (the row of data). Within the custom function, the specific column must be isolated for comparison. For a list of all native array_diff() function variations, see this answer.
To use the first array to filter the second array (and output the retained data from the second array), you must write $array2 as the first parameter and $array1 as the second parameter.
array_diff() and array_intersect() functions that leverage (contain u in their function name) expect an integer as their return value. That value is used to preliminary sort the data before actually performing the evaluations -- this is a performance optimization. There may be scenarios where if you only return 0 or 1 (not a three-way comparison), then the results may be unexpected. To ensure a stable result, always provide a comparison function that can return a negative, a positive, and a zero integer.
When comparing integer values, subtraction ($a - $b) will give reliable return values. For greater utility when comparing float values or non-numeric data, you can use the spaceship operator when your PHP version makes it available.
Codes: (Demo)
PHP7.4+ (arrow functions)
var_export(
array_udiff($array2, $array1, fn($a, $b) => $a['ITEM'] <=> $b['ITEM'])
);
PHP7+ (spaceship operator)
var_export(
array_udiff(
$array2,
$array1,
function($a, $b) {
return $a['ITEM'] <=> $b['ITEM'];
}
)
);
PHP5.3+ (anonymous functions)
var_export(
array_udiff(
$array2,
$array1,
function($a, $b) {
return $a['ITEM'] === $b['ITEM']
? 0
: ($a['ITEM'] > $b['ITEM'] ? 1 : -1);
}
)
);
Output for all version above:
array (
3 =>
array (
'ITEM' => 4,
),
)
When working with object arrays, the technique is the same; only the syntax to access a property is different from accessing an array element ($a['ITEM'] would be $a->ITEM).
For scenarios where the element being isolated from one array does not exist in the other array, you will need to coalesce both $a and $b data to the opposite fallback column because the data from the first array and the second arrays will be represented in both arguments of the callback.
Code: (Demo)
$array1 = array(
array('ITEM' => 1),
array('ITEM' => 2),
array('ITEM' => 3),
);
$array2 = array(
array('ITEMID' => 2),
array('ITEMID' => 3),
array('ITEMID' => 1),
array('ITEMID' => 4),
);
// PHP7.4+ (arrow functions)
var_export(
array_udiff(
$array2,
$array1,
fn($a, $b) => ($a['ITEM'] ?? $a['ITEMID']) <=> ($b['ITEM'] ?? $b['ITEMID'])
)
);
Compares array1 against one or more other arrays and returns the values in array1 that are not present in any of the other arrays.
//Enter your code here, enjoy!
$array1 = array("a" => "green", "red", "blue");
$array2 = array("b" => "green", "yellow", "red");
$result = array_diff($array1, $array2);
print_r($result);

Replace values of one array based on a mapping array

I have two arrays:
$array1 = [29, 'a', 'x', 'c', 11];
$array2 = ['a' => 20, 'x' => 21, 'c' => 23];
I want to get an array that looks like:
$array3 = [29, 20, 21, 23, 11];
I know how to do it with a foreach loop, but I was wondering if there was a way to do it as a one liner, or maybe with some sort of anonymous function.
array_map work as well the other answer :
$array1 = [29, 1=>'a', 2=>'x',3=>'c', 11];
$array2 = ['a'=>20, 'x'=>21, 'c'=>23];
$array3 = array_map(function($a) use($array2){return is_int($a) ? $a : $array2[$a];}, $array1);
You can add them and filter out non-numeric values:
$array3 = array_values(array_filter($array1 + $array2, 'is_numeric'));
If the order is important:
$array3 = array_filter(call_user_func_array(
'array_merge', array_map(null, $array1, $array2)),
'is_numeric');
Then array_values if you need to re-index.
In either case, if you want only integers or floats then use is_int or is_float.
An attempt with a one-liner :
$array1 = [29, 1=>'a', 2=>'x',3=>'c', 11];
$array2 = ['a'=>20, 'x'=>21, 'c'=>23];
$array3 = array_values(array_filter(array_merge($array1,$array2),function($i){return is_int($i);}));
print_r($array3);
// Outputs :
/*
Array
(
[0] => 29
[1] => 11
[2] => 20
[3] => 21
[4] => 23
)
*/
I reckon this looks more elegant than the earlier posted solutions...
Code: (Demo)
var_export(
array_map(fn($v) => $array2[$v] ?? $v, $array1)
);
Attempt to access the mapping array's value by key; if there is no matching key, then default to the original value.
If you don't like to use foreach() you can use array_replace() function. You can learn more about this function in below:
Array_replace($array1 , $array2, $...) in php.net

Removed empty array element to json_encode after

I have simple array
$a = ['a', '', 'b','c','d'];
if i json_encode it i ll have
["a","","b","c","d"]
But if i ll try to remove empty value, with array_filter or array_diff
i ll have
{"0":"a","2":"b","3":"c","4":"d"}
but i dont need array keys to be encoded, i need an encoded array without empty elements and without array keys, how to solve?
Php sandbox example: http://sandbox.onlinephpfunctions.com/code/91635a5df7fcd954dd64fe92089f2beadc81c3c4
Try this:
$a = array_values(array_filter($a));
This resets the keys of your array to be sequential. Consider how the array keys work:
$a = ['a', 'b']; // [0 => 'a', 1 => 'b']
unset($a[0]); // [1 => 'b']
$a = array_values($a); // [0 => 'b']
This resets the array keys
$a = ['a', '', 'b', 'c', 'd'];
echo json_encode(array_values(array_filter($a)));

php. array_values function. how to get mapping from old keys to new keys?

There is function array_values in PHP such that
$array2 = array_values($array1);
$array2 has the same values as $array1 but keys are from
0 to sizeof($array1) - 1. Is it possible to get mapping from old keys to new keys?
EDIT. I will explain on an example:
$array1 = array( 'a' => 'val1', 'b' => 'val1');
$array2 = array_values( $array1 );
so now array2 has next values
$array2[0] = 'val1'
$array2[1] = 'val2'
How get array3 such that:
$array3['a'] = 0
$array3['b'] = 1
To produce a key map you need to first get the keys into a regular array and then flip the keys and values:
$array1_keymap = array_flip(array_keys($array1));
For example:
$array1 = array(
'a' => 123,
'b' => 567,
);
$array1_values = array_values($array1);
$array1_keymap = array_flip(array_keys($array1));
Value of $array1_values:
array(
0 => 123,
1 => 567,
);
Value of $array1_keymap:
array(
'a' => 0,
'b' => 1,
);
So:
$array1['a'] == $array1_values[$array1_keymap['a']];
$array1['b'] == $array1_values[$array1_keymap['b']];
Yes, as simple as
$array2 = $array1;
In this case you would get both values and keys like they are in the original array.
$keyMapping = array_combine(array_keys($array1), array_keys($array2));
This the keys of $array1 and maps them to the keys of $array2 like so
<?php
$array1 = array(
'a' => '1',
'b' => '2',
);
$array2 = array_values($array1);
print_r(array_combine(array_keys($array1), array_keys($array2)));
Array
(
[a] => 0
[b] => 1
)
You can use:
$array3 = array_keys($array1);
Now $array3[$n] is the key of the value in $array2[$n] for any 0 <= $n < count($array1). You can use this to determine which keys were in which places.
If you want to keep the same value of array1 but change the key to index numbers, try this:
$array2 = array();
foreach ($array1 as $key => $value){
$array2[] = $value;
// or array_push($array2, $value);
}
var_dump($array2);

php associative array key order (not sort)

My array:
$data = array('two' => 2, 'one' => 1, 'three' => 3);
Now, with when I iterate the array, the first value that will come up will probably be
$data['two'] // = 2 # index[0]
right?
What if I want to move the $data[1] to the position of $data[0] ?
To rephrase:
How do I make the array look like this (so that 'one' comes up at $data[0])
$data = array('one' => 1, 'two' => 2, 'three' => 3
Why do I need this?
I use code igniter, the table->generate built-in function takes an assoc array and creates a table but offers no method of arranging the columns. This is why I would like to move the columns in the source array.
Two possible solutions (without using array_splice):
1) Create a new array with the new order of the keys.
$new_keys = array('one', 'two', 'three');
$new_data = array();
foreach ($new_keys as $key) {
$new_data[$key] = $data[$key];
}
$data = $new_data;
2) Move the element one upfront, remove it from $data and copy the rest of the array.
function rearrangeData($data) {
$result['one'] = $data['one'];
unset($data['one']);
return array_merge($result, $data);
}
$data = rearrangeData($data);
Take a look at daniele centamore's comment on PHP's array_splice() function, where he provides a couple of functions for moving the elements in an non-associative array.
<?php
// $input (Array) - the array containing the element
// $index (int) - the index of the element you need to move
function moveUp($input,$index) {
$new_array = $input;
if((count($new_array)>$index) && ($index>0)){
array_splice($new_array, $index-1, 0, $input[$index]);
array_splice($new_array, $index+1, 1);
}
return $new_array;
}
function moveDown($input,$index) {
$new_array = $input;
if(count($new_array)>$index) {
array_splice($new_array, $index+2, 0, $input[$index]);
array_splice($new_array, $index, 1);
}
return $new_array;
}
$input = array("red", "green", "blue", "yellow");
$newinput = moveUp($input, 2);
// $newinput is array("red", "blue", "green", "yellow")
$input = moveDown($newinput, 1);
// $input is array("red", "green", "blue", "yellow")
?>
See ksort and uksort.
Here's a working example:
<?php
$data = array('two' => 2, 'one' => 1, 'three' => 3);
print_r($data);
ksort($data);
echo "ksort:\n";
print_r($data);
uksort($data,'cmp');
echo "uksort:\n";
print_r($data);
function cmp($a, $b)
{
$num=' one two three four five six seven eight nine ten';
$ai = stripos($num,$a);
$bi = stripos($num,$b);
if ($ai>0 && $bi>0) {
return ($ai > $bi) ? 1 : -1;
}
return strcasecmp($a, $b);
}
Output:
Array
(
[two] => 2
[one] => 1
[three] => 3
)
ksort:
Array
(
[one] => 1
[three] => 3
[two] => 2
)
uksort:
Array
(
[one] => 1
[two] => 2
[three] => 3
)
Run this:
http://codepad.org/yAK1b1IP
PHP has 13 functions for sorting arrays, by key, by value, by user-defined functions where you can specify that "one" comes before "two". There's also array_shift, array_unshift, array_push and array_pop for moving things onto or off the front or end of the array. You can build a whole new array from the existing one.
I think, you should use asort function:
$data = array('two' => 2, 'one' => 1, 'three' => 3);
$dataOrdered = $data;
asort($dataOrdered);
Run this code

Categories