PHP Intersect Array but not NULL Array - php

I have five 2-D Arrays, (You can assume it like five spreadsheets), I want to take the intersection of the five (I want the common rows of all five in a new spreadsheet) but now I find out that one of the array is a NULL Array, (I find that instead of a spreadsheet, it's just a blank piece of paper), so now I want to ignore it and Intersect the rest of the Arrays... Please suggest a method of doing that...
P.S. - I know it is against the property of intersection because we all know that Intersection of anything with NULL is NULL, but that is not what I want...
P.S. - I also don't know how many Arrays can be empty, I just assumed it to be 1 as an Example, It can be 2, 3, 4 or Even 5... Yes, If it is 5, then returning NULL is perfect but not in any other case... Suppose if 4 Arrays are NULL, then It should return the 5th Array...
Language Used : PHP

You can use array_filter() and a custom implementation of in_array() to check if your array is null
Solution :
$array1 = array(6, 10, 11, 12);
$array2 = array(6, 741, 18, 9, 110, 11, 12);
$array3 = array(8, 10, 11, 20);
$array4 = null;
$array5 = array(9, 10, 11, 12);
function in_array_custom($item, $array)
{
if($array === null){
return true;
}
return in_array($item, $array);
}
function intersect($item)
{
global $array2;
global $array3;
global $array4;
global $array5;
return in_array_custom($item, $array2) && in_array_custom($item, $array3) && in_array_custom($item, $array4) && in_array_custom($item, $array5);
}
print_r(array_filter($array1, "intersect"));
Live example
I share the global solution :
<?php
$arrays = array(
array(6, 10, 11, 12),
array(6, 741, 18, 9, 110, 11, 12),
array(8, 10, 11, 20),
null,
array(9, 10, 11, 12)
);
function in_array_custom($item, $array)
{
if($array === null){
return true;
}
return in_array($item, $array);
}
function in_arrays($item, $arrays)
{
foreach($arrays as $array)
{
if(!in_array_custom($item, $array)) {
return false;
}
}
return true;
}
function intersect($item)
{
global $arrays;
return in_arrays($item, $arrays);
}
print_r(array_filter($arrays[0], "intersect"));
Live example
Here, there is one little issue, that If the first array ($array1) is null, then the code will not work, but that issue can be resolved by taking $array1 as a Union of all the SIX Arrays, (5 Arrays and 1 Union Array), And the Data is shifted to the next array, i.e $array2 now holds the data of $array1, $array3 = $array2 and so on...
P.S. - Union of Arrays can be done like this $array1 = $array2 + $array3 + $array4 + $array5 + $array6;

Related

Remix the string based on array

I have a simple whiteboard question:
Create a function that takes both a string and an array of numbers as arguments. Rearrange the letters in the string to be in the order
specified by the index numbers. Return the "remixed" string. Examples
remix("abcd", [0, 3, 1, 2]) ➞ "adbc"
I submitted my code but it's not being accepted and I am unable to see why. I wrote:
function remix($str, $arr) {
$strArr = str_split($str);
for($i = 0; $i < count($strArr); $i++) {
$arr[$i] = $strArr[$arr[$i]];
}
return implode("", $arr);
}
remix("computer", [0, 2, 1, 5, 3, 6, 7, 4]); // ➞ "cmourpte"
Can anyone see something wrong with it? It's always regular characters, no special cases FYI. Very confused.
It looks like the assignment part is putting the value the wrong way round (i.e. it should be assigning the char at position $i to $arr[$i])...
function remix($str, $arr) {
$strArr = str_split($str);
for($i = 0; $i < count($strArr); $i++) {
$strArr[$arr[$i]] = $str[$i];
}
return implode("", $strArr);
}
which for
echo remix("PlOt", [1, 3, 0, 2]).PHP_EOL;
echo remix("computer", [0, 2, 1, 5, 3, 6, 7, 4]);
gives
OPtl
cmourpte
Just to check, this passes the test.
Well it would seem you missed that the remix was giving an incorrect result.
But I would have done it this way as by default a PHP String is in fact an array already.
function remix($str, $arr) {
$mixed = '';
foreach ($arr as $i) {
$mixed .= $str[$i];
}
return $mixed;
}
echo remix("computer", [0, 2, 1, 5, 3, 6, 7, 4]);
RESULT
cmotperu
In fact if this is the question, the stated answers are wrong in ALL cases.
Create a function that takes both a string and an array of numbers as arguments.
Rearrange the letters in the string to be in the order specified by the index numbers.
Return the "remixed" string.
Examples
remix("abcd", [0, 3, 1, 2]) ➞ "acdb"
The string you'll be returning will have: "a" at index 0, "b" at index 3, "c" at index 1, "d" at index 2, because the order of those characters maps to their corresponding numbers in the index array.
remix("PlOt", [1, 3, 0, 2]) ➞ "OPtl"
remix("computer", [0, 2, 1, 5, 3, 6, 7, 4]) ➞ "cmourpte"

PHP merge 2 arrays with different number of elements, $keys from one, $values from another

I want to merge 2 arrays together that have a different number of elements, using the keys from one and the values from another where/if the keys match. The array that contains the desired values may have less elements in it although I would like to retain the resulting empty keys from the original array. For example:
//Array that contains keys I would like to retain
$arr1 = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
//Array that contains values I'd like to use
$arr2 = array(01=>123, 03=>123, 05=>123, 07=>123, 09=>123, 11=>123);
//The desired result with some valueless elements
$results = array(01=>123, 02, 03=>123, 04, 05=>123, 06, 07=>123, 08, 09=>123, 10, 11=>123, 12);
As you can see the results array retains 12 elements but only applies values to where the keys from the 2 arrays match.
I have tried $results = array_intersect_key($arr1 + $arr2, $arr2); among other PHP functions as well as:
for ($i=1; $i < count($arr1); $i++) {
if (isset($arr2[$i])) {
$arr3[] = $arr2[$i];
} else {
$arr3[] = $arr1[$i];
}
}
print_r($arr3);
No luck as yet.
Thanks in advance!
For arrays like this
$arr1 = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
$arr2 = array(1=>123, 3=>123, 5=>123, 7=>123, 9=>123, 11=>123);
this should work.
foreach ($arr1 as $key) {
$results[$key] = isset($arr2[$key]) ? $arr2[$key] : null;
}
or using some other PHP functions:
$results = array_replace(array_fill_keys($arr1, null), $arr2);
//Array that contains keys I would like to retain
$arr1 = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
//Array that contains values I'd like to use
$arr2 = array(1=>123, 3=>123, 5=>123, 7=>123, 9=>123, 11=>123);
$result = array_fill_keys(
$arr1,
null
);
array_walk(
$result,
function(&$value, $key) use($arr2) {
$value = (isset($arr2[$key])) ? $arr2[$key] : null;
}
);
var_dump($result);
First set your $arr1's values to false to retain just the keys:
$arr1 = array_fill_keys(array_keys($arr1), false); Or if you're generating $arr1 yourself, define it as such to start with: $arr1 = Array(false, false, false, false /* etc. */);
Now use the array union operator:
$result = $arr2 + $arr1;
The + operator returns the right-hand array appended to the left-hand array; for keys that exist in both arrays — from the docs: http://php.net/manual/en/language.operators.array.php)
Then if required sort the array by key: ksort($array);

Create sorted array from multiple pre-sorted arrays [duplicate]

This question already has answers here:
easier way to flatten or merge php array than this?
(2 answers)
Sort array by value alphabetically php
(4 answers)
Closed 6 months ago.
I would like to create a sorted array from a variable number of pre-sorted arrays.
Given {A1, ..., An} which are pre-sorted arrays, I would like to create At, which is the combination of {A1, ..., An} and is sorted in the same way.
Example :
Given :
A1 = [2, 4, 9, 16]
A2 = [-3, 4, 98, 116]
...
An = [1, 7, 17, 76, 512]
I would like :
At = [-3, 1, 2, 4, 4, 9, 16, 17, 76, 98, 116, 512]
What it is the most efficient way to compute this array ?
Thanks
It's simple. We have A1..AN - pre-sorted lists and same amount of indexes I1..IN set to zero (for zero-based lists). Now we need to form merged list from this. To do this we need to find smallest (or biggest depends on what's initial sort order) element from all these lists. It's obvious that this is one of the A1[I1] A2[I2] .. AN[IN] element. So we just go through all these elements and choose smallest. Let's say it was element in A2. We put it into our new big list and increment I2. Now we have same situation as in the beginning and should repeat all these steps again or stop if all lists exhausted.
Example:
A1 = [1, 2, 6]
A2 = [2, 4, 5]
A = []
I1 = 0
I2 = 0
-------------
A = [1]
I1 = 1
I2 = 0
-------------
A = [1, 2]
I1 = 2
I2 = 0
-------------
A = [1, 2, 2]
I1 = 2
I2 = 1
...
I have implemented a function doing what I want.
What do you think of the performance ? Do you have any advice to improve it ?
Sorting function:
function sortPreSortedArrays($arrays, $comparisonFunction, $order = 'asc')
{
$sortedArray = array();
/* Sort */
while(sizeof($arrays) !== 0)
{
/* Find the greatest value */
$max = true;
$keyMax = -1;
foreach($arrays as $key => $array)
{
if($max === true || $comparisonFunction(end($array), $max))
{
$max = end($array);
$keyMax = $key;
}
}
/* Take the greatest value */
array_push($sortedArray, array_pop($arrays[$keyMax]));
if(sizeof($arrays[$keyMax]) === 0) unset($arrays[$keyMax]);
}
/* Return */
if($order === 'asc')
return array_reverse($sortedArray);
else
return $sortedArray;
Comparison function:
function compareLogArrayDate($log1, $log2)
{
$t1 = $log1['date'];
$t2 = $log2['date'];
return ($t1 > $t2) ? true : false;
}
Edit: In order to improved the performancse, I have tried do use the most efficient array functions (array_pop O(1) instead of array_shift O(n). Nevertheless I am still using unset. :|
$A1 = [2, 4, 9, 16];
$A2 = [-3, 4, 98, 116];
$An = [1, 7, 17, 76, 512];
// create arrays of ith elements
$return = call_user_func_array('array_map', [null, $A1, $A2, $An]);
// sort arrays
array_walk($return, 'sort');
// create new arrays
$return = call_user_func_array('array_merge', $return);
// remove null values lefted after first operation
$return = array_filter($return, 'is_scalar');
var_dump($return);

Finding the index of an object in an array when there are multiple possibilities

I have an array, and I want to find all of the indexes of a certain object in the array. When I use array_search, it only returns the first index in which the object can be found.
echo array_search(3, array(3, 3, 4));
This returns 0, but I want to know that both indexes 0 and 1 have the integer 3 as their object. Is there a way of doing this without using a for loop?
Try array_keys() method :
$array = array(3, 3, 4);
print_r(array_keys($array, "3"));
For reference:
array_keys() — Return all the keys or a subset of the keys of an array Info & usuage examples : http://php.net/manual/en/function.array-keys.php
As an alternative to array_keys, array_filter() retains associativity
$key = 3;
$array = array(1, 3, 3, 4, 3, 5);
$result = array_filter(
$array,
function ($item) use ($key) {
return ($item == $key);
}
);
var_dump($result);

dynamically build and populate table with php array

let's say I have these two arrays:
$array1 = array(1, 2, 3, 4, 5);
$array2 = array(6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
As you can see, my arrays have different lengths. What I'm trying to do is to input these array values into an HTML table with the first column containing the values coming from $array1 and the second column containing the values coming from $array2. So, in this case right here, I should have a table of 10 rows (because $array2 contains 10 elements) and 2 columns (because I have 2 arrays). Also, I cannot know in advance which array is going to have more elements than the other (so, $array1 could be bigger than $array2, they could also have equal sizes). So, depending on which array has more elements, the number of rows in my table should adjust accordingly.
Any idea please?
Thank you
$array2 = array(6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
$array1 = array(1, 2, 3, 4, 5);
$a=count($array1);
$b=count($array2);
echo "<table border=1><tr><th>Array1</th><th>Array2</th></tr>";
if($a > $b)
{
for($i=0;$i<$a;$i++)
{
echo "<tr><td>".$array1[$i]."</td>";
echo "<td>".$array2[$i]."</td></tr>";
}
}
if($b > $a)
{
for($i=0;$i<$b;$i++)
{
echo "<tr><td>".$array1[$i]."</td>";
echo "<td>".$array2[$i]."</td></tr>";
}
}
echo "</table>";
Try thinking of some thing like below
this will give you atleast an idea of how to iterate them.
$array = array($array1,$arry2);
for($i = 0; $i < $array.length; $i++)
{
$rows = $array[$i];
for($j=0; $j< $rows.length; $rows++){
}
}
i hope you can figure out the logic required from this . in case it doesnt work out post comment and we will walk through

Categories