Warning: in_array() expects parameter 2 to be array, null given (loop) - php

I'm looping for string overlaps between two arrays, deleting those values where there is one, so that only the empty values of $check remain, in this case $check[5].
The second one, $check, is multidimensional.
$names = ["bob", "selena", "hailey", "rob", "justin", "robocop"];
$check = [
["justin"], //bob
["justin", "selena", "robocop"], //selena
["justin"], //hailey
["justin", "rob"], //rob
[], //justin
["justin", "selena", "bob"] //robocop
];
for ($i = 0; $i < count($names); $i++) {
for ($j = 0; $j < count($check); $j++) {
if (in_array($names[$i], $check[$j])) {
unset($check[$j]);
}
}
}
The first loop runs through $names, the second through $check.
If the current string from $names ($names[i])
is present in the current array of $check ($check[j])
the array is removed.
However, the console prints a warning: in_array() expects parameter 2 to be array, null given. I find this strange, because $check[j] should be equal to one of the arrays inside of $check.
Is there any way I can fix this?

After a few iterations of the outer loop, you will have unset most of $check. With a for loop like that, you're counting on specific numeric keys being there, but since you unset them, their values are undefined, a.k.a. null.
You can avoid this by using foreach loops instead.
foreach ($names as $name) {
foreach ($check as $key => $array) {
if (in_array($name, $array)) {
unset($check[$key]);
}
}
}

As you are keep on unsetting the $check array, the size of the $check array will go down. Hence the $check won't return a value for the higher values of $j
You can do a minor modification in this code segment as follows
$checkcount = count($check);
for ($i = 0; $i < count($names); $i++) {
for ($j = 0; $j < $checkcount; $j++) {
if (isset($check[$j]) && in_array($names[$i], $check[$j])) {
unset($check[$j]);
}
}

Related

remove duplicate arrays in loop

I have an associative array that might contain duplicates. I am trying to loop through the array and compare the current element with the next element in the array. If there is a duplicate, it should be removed.
The code below removes one instance of the element. In the test array I'm using, I have 3 duplicate part numbers, but my code only removes one. I'm left with two. I only want one to remain.
$length = count($items);
for($i = 0; $i < $length -1; $i++){
if($items[$i]['part_number'] == $items[$i+1]['part_number']){
unset($items[$i+1]);
$items = array_values($items);
}
}
What am I doing wrong here?
You need to loop backwards through the array, and delete the current item.
$length = count($items);
for($i = $length - 1; $i > 0; $i--){
if($items[$i]['part_number'] == $items[$i-1]['part_number']){
unset($items[$i]);
}
}
becuase your code is
The $ items value is in the for statement.
if you want unique array, you have to array_unique function
http://php.net/manual/en/function.array-unique.php
In your case after you unset element, $i++ in for loop, you reindexed your array and you skip one element. Add $i-- if you unset item. Or you can reindex your array after for loop.
This is also a very simple example you can start improving with.
<?php
$test = ['sample', 'sample', 'sample', 'not', 'not', 'no', 'no'];
$test2 = [];
$k = 0;
foreach ($test as $key => $value) {
if ($key == 0) {
$test2[$k] = $value;
$k++;
} else {
if ($test2[$k - 1] != $value) {
$test2[$k] = $value;
$k++;
}
}
}
$test = $test2;
var_dump($test);
One dirty hack is to check again if you have a duplicate by decreasing $i.
for($i = 0; $i < $length -1; $i++){
if($items[$i]['part_number'] == $items[$i+1]['part_number']){
unset($items[$i+1]);
$items = array_values($items);
$i--;
}
}
This way it will again test your previous value against next item in array.
So if 0==1, then next time if 0==2.
Your code did 0==1 then (2)==(3).

For Loop Display Fact

I'm trying to figure out why I am getting a undefined offset of 1 for this for loop I'm writting. I have an array ($facts) that has specific key values pairs and I'm trying to see if on each iteration the $i matches one of the keys in the array. If the key isset and in the array I need to display the value of that key.
for ($i = 1; $i <= 100; $i++) {
if (isset($i) && in_array($i, $facts[$i])) {
echo $facts[$i];
}
echo $i;
}
UPDATE: Use the function isset to test if the incremented value equals one of the keys in the $facts array. If there is a key that matches, display the value after the number.
I think this is the correct way of checking (removing the in_array()).
for ($i = 1; $i <= 100; $i++) {
echo $i; // Now the number is first.
if (isset($facts[$i])) {
// This is only echoed if $i exists as a key.
echo $facts[$i];
}
}
If you only want to show the number if the fact exists, move echo $i inside the if-statement (or better yet, use foreach($facts as $key => $value) in that case).
You could check $facts[$i]
for ($i = 1; $i <= 100; $i++) {
if (isset($facts[$i]) && in_array($i, $facts[$i])) {
echo $facts[$i];
}
echo $i;
}

Return values of an array from behind (last element) php

say I have an array
$test_backwards=array("something1","something2","something3");
this is just a testing example and it's important to note that values will be added dinamically in my final array. so is it possible to dynamically return values from behind, namely starting from the last element?
something like this but backwards
for($i=0;$i<count($test_backwards);$i++) {
echo $test_backwards.'<br>';
}
Just start at the end and decrement your index:
for ($i = count($test_backwards) - 1; $i >= 0; $i--) {
echo $test_backwards[$i].'<br>';
}
or use array_reverse() (slower):
$test_backwards = array_reverse($test_backwards);
for ($i = 0; $i < count($test_backwards); $i++) {
echo $test_backwards[$i].'<br>';
}
You can also use array_pop(), if you do not need to keep this array. Or you can assign it to a temp array and then array_pop it, it will get and delete value from last.
$temp = $test_backwards;
while(($item = array_pop($temp)) !== NULL ) {
echo $item;
}

Reorder elements in array evenly

Say i have:
$array = (1,1,1,1,2,2,2,2,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
What I'm trying to achive is to reorder elements evenly in it.
PHP's function shuffle() don't fits here, because i want some distance between same digits. So 1's has to be somewhere in the beginning of array, in the middle and in the end too.
I google about Fisher-Yates_shuffle algorithm, but it seems to work exactly like shuffle().
Thanks in advance!
I think this is close to what you ask: A constant, reasonably even distribution of the items in an array.
// The input array. 0s are regarded as blanks.
$array = array(1,1,1,1,2,2,2,2,3,3,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
// Count the times each item occurs. PHP will probably have a function for that, but I don't know.
$counter = array();
foreach ($array as $item)
{
// Zeros are infill. Don't process them now, only process the other numbers and
// the zeros will occupy the remaining space.
if ($item === 0)
continue;
if (!array_key_exists($item, $counter))
$counter[$item] = 0;
$counter[$item]++;
}
// Reverse sort by quantity. This results in the best distribution.
arsort($counter);
// Pre-fill a new array with zeros.
$resultCount = count($array);
$result = array_fill(0, $resultCount, 0);
// Distribute the items in the array, depending on the number of times they occur.
foreach ($counter as $item => $count)
{
// Determine the division for this item, based on its count.
$step = $resultCount / $count;
// Add the item the right number of times.
for ($i = 0; $i < $count; $i++)
{
// Start with the index closest to the preferred one (based on the calculated step).
$index = 0;
$startIndex = (int)($step * $i);
// Count up until a right index is found.
for ($index = $startIndex; $index < $resultCount; $index++)
{
if ($result[$index] === 0)
{
$result[$index] = $item;
break;
}
}
// If no proper index was found, count fown from the starting index.
if ($index === $resultCount)
{
for ($index = $startIndex; $index >= 0; $index--)
{
if ($result[$index] === 0)
{
$result[$index] = $item;
break;
}
}
}
// Still no proper index found, that shouldn't be possible. There's always room.
if ($index === -1)
{
throw new Exception('This cannot not happen');
}
}
}
var_dump($result);
For array:
1,1,1,1,2,2,2,2,3,3,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
It returns:
3,2,1,0,3,0,0,0,3,0,2,1,3,0,0,0,3,0,0,0,0,3,2,1,0,3,0,0,0,3,0,2,1,3,0,0,0,3,0,0,0,0
For array:
1,1,1,1,2,2,2,2,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,0
It returns:
4,4,3,4,3,4,2,4,3,4,2,4,3,4,1,4,3,4,1,4,0,4,4,3,4,3,4,2,4,3,4,2,4,3,4,1,4,3,4,1,4,0
Which I think is a neat distribution. Thanks to datdo for the idea of sorting the intermediate array.

Compare all values in php array with the other values

I have a php array
How can I compare all values of this array and filter out values based on custom logic (callback function maybe).
Essentially, I want to compare each array value with every other value within the array and based on some custom logic, either keep the value or remove it from the array
Thanks
Probably you have to do it manually:
function your_callback($a, $b)
{
return $a != $b;
}
$array = array(/** Your array here... **/);
$n = count($array);
$filtered = array();
for($i = 0; $i < $n; $i++)
{
$ok = true;
for($j = 0; $j < $n; $j++)
{
if($j != $i && !your_callback($array[$i], $array[$j])
{
$ok = false;
break;
}
}
if($ok)
array_push($filtered, $array[$i]);
}
unset($array);
$array = $filtered;
This example will filter unique values of array for example; change your_callback definition to implement other logic.
You can call array_map, passing your callback as the first argument, and passing your array twice, as the second and the third argument. In the callback function, you loop through the "second" array and return the element if you want.
If you are looking to compare values of one array with values of another array in sequence then my code is really simple: check this out it will work like this:
if (1st value of array-1 is equal to 1st value of array-2) { $res=$res+5}
if($_POST){
$res=0;
$r=$_POST['Radio1']; //array-1
$anr=$_POST['answer']; //array-2
$arr=count($r);
for($ac=0; $ac<$arr; $ac++){
if($r[$ac]==$anr[$ac]){
$res=$res+5;
}
}
echo $res;
}

Categories