PHP Array of arrays made unique - php

I have an array of arrays as following:
$a = array(
1 => array("sport", "geo"),
2 => array("sport", "geo", "history"),
3 => array("geo", "history"),
4 => array("golf", "sport"),
...
);
From that I need to get keys, in such a way so that values are unique.
So from that I would need to get something like:
$b = array( 1, 3, 4 );
$a[2] would be cut out, since it has the same values as $a[1], but since $a[2] is not there, $a[3] is fine.
If some values get completely cut out, that's fine. I will have 30+ keys, from which I need to get 10, which have unique values.
Key is a question ID, and values are tags.
I want to get 10 questions, which are different from each other (so that I don't get 10 questions about Sport).
I tried array_unique(), but that just returns this:
Array (
[1] => Array (
[0] => sport
[1] => geo
)
)
which doesn't seem to help much.
Can you guys point me towards something that could help me?
I guess I could try to list all possible categories, make that array unique, sort it by random. I would need to preserve Keys, but Keys are unique...

you can use array_diff() to detect unique tags
Returns an array containing all the entries from array1 that are not present in any of the other arrays.
Then use array_merge() to store unique value to our $tags variable
Merges the elements of one or more arrays together so that the values of one are appended to the end of the previous one. It returns the resulting array.
<?php
$a = array(
1 => array("sport", "geo"),
2 => array("sport", "geo", "history"),
3 => array("geo", "history"),
4 => array("golf", "sport")
);
$tags = [];
foreach($a as $tag){
$tags = array_merge($tags, array_diff( $tag, $tags));
}
print_r($tags);
Output :
Array
(
[0] => sport
[1] => geo
[2] => history
[3] => golf
)

Just iterate through the initial array of questions, every time save the value (array of tags) to another temporary array with checking if actual tags already exists in temporary array - if not add the question to temporary array, if exists go next. Do it until you have 10 questions in your temporary array, if you finish the question array without already having 10 questions - repeat the iteration but this time add other questions even if the tags are repeating - until you have 10.

Related

PHP array sort with forced the first row [duplicate]

This question already has answers here:
Move array item with certain key to the first position in an array, PHP
(9 answers)
move array element to the first position but remain order
(4 answers)
Move an array element to a new index in PHP
(9 answers)
Move Value in PHP Array to the Beginning of the Array
(12 answers)
Move array element with a particular value to top of array
(2 answers)
Closed 2 months ago.
How to sort an array at PHP to force selected row as a first ?
My array is
array[]=array(id=>'a', content=>'lemon');
array[]=array(id=>'b', content=>'apple');
array[]=array(id=>'c', content=>'banana');
array[]=array(id=>'d', content=>'cherry');
How to sort the array to force
array[]=array(id=>'b', content=>'apple');
as a first row and doesn't matter the rest (apple is the key).
And in other example turn sort to get
array[]=array(id=>'d', content=>'cherry');
as a first row and doesn't matter the rest (cherry is the key).
Another way to do this is to effectively rotate the array using array_slice, bringing the element you want to the start:
$first = 'apple';
$k = array_search($first, array_column($array, 'content'));
$array = array_merge(array_slice($array, $k), array_slice($array, 0, $k));
print_r($array);
Output:
Array (
[0] => Array ( [id] => b [content] => apple )
[1] => Array ( [id] => c [content] => banana )
[2] => Array ( [id] => d [content] => cherry )
[3] => Array ( [id] => a [content] => lemon )
)
Demo on 3v4l.org
There are 2 ways I can think of doing this. The first is as Ultimater in the comments suggest to extract the matching row, then sort and then add the row back in...
$first = 'apple';
$array = [];
$array[]=array('id'=>'a', 'content'=>'lemon');
$array[]=array('id'=>'b', 'content'=>'apple');
$array[]=array('id'=>'c', 'content'=>'banana');
$array[]=array('id'=>'d', 'content'=>'chery');
$firstElement = array_search($first, array_column($array, "content"));
$row = $array[$firstElement];
unset($array[$firstElement]);
sort($array);
array_unshift($array, $row);
print_r($array);
The second is to use usort and add specific clauses in that if the key matches the row you want first, then it will always force it to the first row...
$first = 'apple';
usort($array, function ($a, $b) use ($first){
if ( $a['content'] == $first) {
return -1;
}
if ( $b['content'] == $first) {
return 1;
}
return $a <=> $b;
});
print_r($array);
(I've used <=> in this which is PHP 7+, there are alternatives if you need to use PHP 5).
If as your comment suggests that there is no need to sort the rest of the data, then the first set of code minus the sort() should do.
One other option - if id:content is one to one, we can index the array by content and merge with an array with a single empty "apple" key (or whichever content value you're looking for).
$array = array_merge(['apple' => []], array_column($array, null, 'content'));
If the resulting string keys are undesirable the array can be reindexed with array_values.
If the array only contains id and content and id:content is in fact one to one, a "dictionary" of key-value pairs will be handier to deal with than a list of rows like this and it would probably be better to set the array up that way to begin with if possible.
If id:content is not one to one, then... never mind. ;-)

2 or more arrays from a list

I am quite not able to get the logic for my requirement.
Lets consider I have an array
Array
(
[0] => 1
[1] => 1
[2] => 2
[3] => 1
[4] => 3
[5] => 3
)
I would like to split the below array on the basis if the array element matches its previous element.
i.e in the above example value at [1] matches the value at [0]. Hence put it into the same array as [0]. Now check if the value at [2] matches the value at [1] if it matches put it into the same array, if not put it into a different array. The process continues.
Below is an example of the desired outpout.
Array
(
[0] => 1
[1] => 1
)
Array
(
[0] => 2
)
Array
(
[0] => 1
)
Array
(
[0] => 3
[1] => 3
)
Thanks for your help in advance.
Justin
you can obtain that result in a loop checking on previous element. the output can be an array of arrays! (or anything you would prefer.. do your thing here)
$array1 = array(1, 1, 2, 1, 3, 3);
$output_array=array();
$previous_value="";
$output_array_index=0;
foreach ($array1 as $value) {
if($value != $previous_value){
$output_array_index+=1;
}
$output_array[$output_array_index][]=$value;
$previous_value=$value;
}
print_r($output_array);
so, let me know if you need more pointers! array logic is fun, and php will let you do alot, out of the box. though this specific need is not covered, have a look when you have a minute # the manual, it'll save you time in the future, guarantee http://php.net/manual/en/ref.array.php
This question is a bit confusing but doesn't sound too difficult to implement if I'm understanding it correctly. All you need to do is have a temporary array (or array list) that checks user input. If that user input happens to be the same as the previous input (you can keep a counter variable and check to see if ArrayList.get(counter) == ArrayList.get(counter-1)). Keep adding things to this temporary arrayList and once you have a number that is different, just iterate through the arraylist and add it to a new array.
Another question you have to consider is how you are going to store all these arrays. For that you may want to create an ArrayList containing Arrays. That way after you find user input that is different from the previous input you can just use the toArray method provided with the ArrayList class and add it to the ArrayList containing all of your separate Arrays!
Hope this helps!

How do I reorganize an array in PHP?

I am trying to figure out how to reorganize an array..
I have a multidimensional array(Ill call that original_array) and I would like to take the first array within original_array and set the values as keys in a new array. I also want to take the values of the second array in original_array and make them keys and then set the values of the third array in original_array as the values for those keys.
Here is an example of original_array:
Array (
[id] => Array (
[0] => 1
[1] => 3
)
[reward] => Array (
[0] => Movie
[1] => Trip
)
[cost] => Array (
[0] => 50
[1] => 200
)
)
Basically what I would like to do is look like this:
Array (
[1] => Array (
[Movie] => 50
)
[3] => Array (
[Trip] => 200
)
)
Is there a simple and elegant way to merge these like this?
I have spent hours trying to figure this out using array_merge, array_merge_recursive.. etc. And have search SO far and wide for a similar questions, but I haven't found anything that does what I am after.
I was able to correctly combine the 2nd and 3rd arrays in original_array with array_combine. But, I am at a loss as how to combine that result with the 1st array's values in original_array.
Thanks in advance to any help!
Well, the dirty way would be just use combine array functions like array_combine with the input:
$new_array = array_combine(
$array['id'], // parent keys
// combine chunked combined sub keys :p
array_chunk(array_combine($array['reward'], $array['cost']), 1, true)
);
There may be some incantation of array_*() merging functions that could produce what you're looking for, but it is far easier to just iterate over the original array's [id] sub-array and use its values to create new sub-array keys in a different output array.
// To hold your output
$output = array();
// Iterate the original array's [id] sub-array
foreach ($original['id'] as $idxkey => $newkey) {
// Add a sub-array using $newkey to the output array
$output[$newkey] = array(
// Using the index (not value), retrieve the corresponding reward
// value to use as the new array key
// and corresponding cost to use as the new subarray value
$original['reward'][$idxkey] => $original['cost'][$idxkey]
);
}
Here is a demonstration: https://3v4l.org/2pac3
This should work for you:
First you can get the keys for the main array into a separate variable with array_shift(), which will just remove the first element from your array, which is the array holding the keys.
Then use array_map() to loop through both of your subArrays and use reward as key with the cost values as value and return it in an array. At the end you just have to array_combine() your keys $keys with the new created array.
Code:
<?php
$keys = array_shift($arr);
$result = array_combine($keys, array_map(function($k, $v){
return [$k => $v];
}, $arr["reward"], $arr["cost"]));
print_r($result);
?>
You might wanna take a look at BaseArrayHelper from Yii 2.0 Framework.
Although this file is part of a framework it has only very few dependencies and you should be able to use just this file or parts of it in your code with small modifications.
An example for your use case can be found in the index() method.

PHP -modify value of last accessed element in multidimensional associative array

I am reading a GEDCOM-formatted family tree flat file, and producing an array from the data for staging into table. If I encounter the values CONC <some value>, then, instead of adding an element, I need to append <some value> to the value of the last element that was just inserted (regardless of dimension depth).
I tried with current(...) etc but does this work for a multidimensional associative array?
please consider following element in an array:
[#N163#] => Array ( [INDI] => Array ( [TEXT] => Some data of this person) )
if the next line reads "1 CONC including his profession"
instead of adding a line as such
[#N163#] => Array (
[INDI] => Array ( [TEXT] => Some data of this person)
[INDI] => Array ( [CONC] => including his profession) )
I would like the array to look as follows:
[#N163#] => Array (
[INDI] => Array ( [TEXT] => Some data of this person including his profession) )
What I have researched thus far:
end($theArray)
to set pointer to last inserted element followed by $theArray[key($theArray)] = .... to update this element.
But I did not get this method to work for multidimensional arrays and/or it became really messy.
And:
merging two arrays using e.g. += notation,
but this only seems to overwrite a new element, not affect the last one, if keys are same
And:
examples with foreach calls, which does not help in my case.
Hope somebody can shed some light... many thanks!
When you adding $array[#N163#][INDI][TEXT] = 'smtng'; you can save position
$pos = &$array[#N163#][INDI][TEXT];
And if you need concatenate, write
$pos .= "concate line";

Compare elements in multidimensional array

I have a multidimensional array where one of the elements looks like the following:
Array
(
[9-0048-1:G07] => Array
(
[wafer] => 9-0048-1
[cell] => G07
[isc] => 2.922336
[start_time] => 2014-07-21 09:51:56
)
I set the key of each element equal to the wafer and cell.
Each wafer has 5 different types of cells.
I want to compare the 5 different cells in each wafer and do some calculations.
The 5 different type of cells are C09, c05, K05, K09, and G07. I want to be able to
do calculations with the ISC of each cell. Such as I want to compare the ISC of two cells (c09 and c05) and find the uniformity ((bigger value - lower value)/bigger value) of the two. I'm not sure how to go about being able to compare the different values.
This code may help you, let's say your multidimensional array is $Array and you need to compare elements with wafer="9-0048-1", then this code will help you get all the elements with the wafer="9-0048-1" in an array
$wafer_to_compare = "9-0048-1";
$array_to_compare = [];
foreach ($Array as $key => $array)
if(strpos($key, $wafer_to_compare)!=null)
$array_to_compare[] = $array;

Categories