PHP Permutations with exception of similar sequence - php

My permutation/combinations of data
$combinations = [[]];
$data = [
['alteration1', 'alteration2', 'alteration3', 'alteration4' ... upto 5 each],
['alteration1', 'alteration5', 'alteration6', 'alteration7' ... upto 5 each],
['alteration8', 'alteration9', 'alteration10', 'alteration5' ... upto 5 each],
... upto 6 max
];
$length = count($data);
for ($count = 0; $count < $length; $count++) {
$tmp = [];
foreach ($combinations as $v1) {
foreach ($data[$count] as $v2)
$tmp[] = array_merge($v1, [$v2]);
}
$combinations = $tmp;
}
print_r($combinations);
The script would generate such sets
0 => array:3 [▼
0 => "alteration1"
1 => "alteration1"
2 => "alteration8"
]
1 => array:3 [▼
0 => "alteration1"
1 => "alteration1"
2 => "alteration9"
]
... the issue begins when I start getting the same sequences of data in my case array index 0 and 20 would be exactly the same despite any position.
20 => array:3 [▼
0 => "alteration8"
1 => "alteration1"
2 => "alteration1"
]
21 => array:3 [▼
0 => "alteration1"
1 => "alteration9"
2 => "alteration1"
]
$final = []; // remove duplicates
The basic idea is to keep $combinations array's unique (alteration1,alteration2,alteration3) is equal to (alteration3,alteration1,alteration2) therfore it should be skipped in the $final array. I haven't really found anything around SO and google. Thanks for the help. $data dimentions [ from 1 - 6 ], each array inside can be [ 1 - 6 ]. Following script might not be working as expected .
http://sandbox.onlinephpfunctions.com/code/3ad5084386c2185f7619aaac152b638873039ee8

We iterate over the data and find unique elements first for each set using array_unique.
We then natsort them to get a sorted form and serialize them using implode(). By doing this, we would get the same serialized code for sets ABC,CBA,BAC etc.
We then find duplicates using keys check inside a variable, say $set. If the serialized key is set, we exclude it from the results, else we include it in our final results.
Snippet:
<?php
$data = [
['alteration1', 'alteration4',],
['alteration2','alteration3'],
['alteration2','alteration3'],
[]
];
$combinations = [[]];
foreach($data as $index => $current_data){
$current_data = array_unique($current_data);
if(empty($current_data)) continue;
$temp_combinations = [];
foreach($current_data as $value){
foreach($combinations as $each_combination){
$temp_combinations[] = array_merge($each_combination,[$value]);
}
}
$combinations = $temp_combinations;
}
$set = [];
$unique_combinations = [];
foreach($combinations as $each_combination){
natsort($each_combination);
$serialized_form = implode(",",$each_combination);
if(isset($set[$serialized_form])) continue;
if(empty($each_combination)) continue;
$unique_combinations[] = $each_combination;
$set[$serialized_form] = true;
}
print_r($unique_combinations);
Demo: https://3v4l.org/Do6oH

Related

Multidimensional Array Search by Multiple Keys given as Variable?

I have a multidimensional array which has keys and key has values or have another array with keys and values so I want to search by keys but in input like 230 is user input
and it will go to 3 then 4 then 1 if result is a value but not an array it must print the value like
input = 230 result should be = "3-4-1"
so I need to str_split the number and search it 1 by 1 if first number is array then look for second kinda
edit1 = I found the way to split the key
//edit1
$keys = "021";
$keysSplit =str_split($keys, strlen($keys)/strlen($keys));
echo $keys[0];
//edit 1 ends
$arr = [0 => [0=>"1-1", 1 => "1-2" , 2=>"1-3", 3=>[0=>"1-4-1", 1 => "1-4-2" , 2=>"1-4-3"]],
1 => [0=>"2-1", 1 => "2-2" , 2=>"2-3"],
2 => [0=>"3-1", 1 => "3-2" , 2=>"3-3", 3=>[0 =>"3-4-1" , 1=> "3-4-2"]],
];
$keys = "021";
function searchByKey($array , $keys){
$result = [];
$keys = "021";
$keys =str_split($keys, strlen($keys)/strlen($keys));
$key1 = $keys[0];
$key2 = $keys [1];
$key3 = $keys [2];
foreach ($array as $key1 => $value){
if (is_array($value)){
$key1 = null;
$key1 = $key2;
$key2 = $key3;
return searchByKey($value , $key1);
}
else {
$result=$value;
echo $result;
}
}
}
$arr = searchByKey($arr, $keys);
The function only works as key and value given and it will print every key and value on the key it asked first so its not the thing I wanted to do could anyone help and explain?
Answer given by #Anggara I made it in to function ;
$input = "11";
function searchByNumber($array, $input){
$result = $array;
for ($i = 0; $i < strlen($input); $i++) {
if (is_array($result)) {
$result = $result[$input[$i]];
} else {
$result = "Does not exists";
break;
}
}
echo $result;
}
$arr = searchByNumber($arr, $input);
You can access char in string like accessing an array. For example:
$input = "230";
// $input[0] is "2"
// $input[1] is "3"
// $input[2] is "0"
So my approach is to loop for each character in input key, and look for corresponding value in $arr. Each iteration will set found array element into variable $result. If the searched key does not exist (ex: "021"), print error message.
<?php
$arr = [
0 => [
0 => "1-1",
1 => "1-2",
2 => "1-3",
3 => [
0 => "1-4-1",
1 => "1-4-2",
2 => "1-4-3"
]
],
1 => [
0 => "2-1",
1 => "2-2",
2 => "2-3"
],
2 => [
0 => "3-1",
1 => "3-2",
2 => "3-3",
3 => [
0 => "3-4-1",
1 => "3-4-2"
]
],
];
$input = "230";
$result = $arr;
for ($i = 0; $i < strlen($input); $i++) {
if (is_array($result)) {
$result = $result[$input[$i]];
} else {
$result = 'Can not traverse path';
break;
}
}
echo $result;
After splitting the keys
for($i=0;$i<strlen($keys);$i++){
$arr = $arr[$keys[$i]];
}
if(is_array($arr)){
echo json_encode($arr);
}else{
echo $arr;
}
You need a loop, which will go through the keys one by one and assigning into the array.

Is there a better way of adding values of the same array index in laravel using foreach that is memory efficient?

Here is my code to achieve:
The values of $categoryRatings are the following arrays:
$categoryRatings = array:2 [
2 => array:2 [
1 => 50.0
2 => 35.0
]
3 => array:2 [
1 => 55.0
2 => 45.0
]
]
$indexes = [];
foreach ($categoryRatings as $categoryRating) {
foreach ($categoryRating as $key => $value) {
foreach ($categories as $category) {
if ($category->id == $key) {
$indexes[$category->id] = isset($indexes[$category->id]) ? ($indexes[$category->id] + $value) : $value;
}
}
}
}
$overAllCategoryRating = [];
foreach ($categories as $category) {
$overAllCategoryRating[$category->id] = $indexes[$category->id]/sizeof($categoryRatings);
}
And the output of $overallCategoryRating is equal to:
array:2 [
1 => 52.5
2 => 40.0
]
The $categories here is a collection where I used the id as key so that I can assign the results to its key for use in my front end.
Is there some ways to optimized this code for memory efficient since when large data is computed it won't get results fast because of many foreach loop.
You can use
$first = collect($categoryRatings)->avg(1) // Result: 52.5
$second = collect($categoryRatings)->avg(2) // Result: 40.0

Get data from multiple array in Controller

I have country list in array with multiple array, like:
public static function listCountries()
{
$this->country = array(
array(1, 'SAD', 'sad.png'),
array(2, 'Argentina', 'argentina.png'),
array(3, 'Australija', 'australija.png'),
array(4, 'Novi Zenland', 'noviz.png'),
array(5, 'Belgija', 'belg.png'),
array(6, 'Nizozemska', 'nizozemska.png')
);
}
But when i do foreach for array, i'm getting this:
//From DB
$item->country = "1,4";
$item->country = explode(",", $item->country);
for($i=0; $i < count($item->country); $i++) {
$index = $item->country[$i];
if( !empty($this->country[$index]) ) {
$item->country[$i] = $this->country[$index];
}
}
$item->country = implode(",", $item->country);
echo $item->country;
But i'm getting something like this:
array:2 [▼
0 => array:3 [▼
0 => 5
1 => "Belgija"
2 => "belg.png"
]
1 => array:3 [▼
0 => 2
1 => "Argentina"
2 => "argentina.png"
]
]
1 = SAD, 4 = Novi Zenland, not Belgija and Argentina
There is no good country, also no data what i want. How to fix this?
You can use this foreach loop to go through the other array and swap the string if the number matches:
$item->country = "1,4";
$item->country = explode(",", $item->country);
for($i=0; $i < count($item->country); $i++) {
$index = $item->country[$i];
foreach($this->country as $c) {
if($c[0] == $index) {
$item->country[$i] = $c[1]; // or $item->country[$i] = $c; if you want all three items
break;
}
}
}
$item->country = implode(",", $item->country);
echo $item->country;
// Should output: SAD,Novi Zenland
The indexes in arrays are 0-based, which means that:
$index = $item->country[$i];
Has to become
$index = $item->country[$i - 1];
To correlate with the country ids. Otherwise, it is always one off. This is assuming that the ids are always ordered from least to greatest, and all ids are a continuous range.

json array elements to array

$cuisines = RestaurantProfile::select('cuisines')->get();
$cuisines_array = array();
foreach ($cuisines as $cuisine) {
$string = implode(",",json_decode($cuisine, true));
$array = explode(",", $string);
foreach ($array as $single) {
if (!in_array($single, $cuisines_array)) {
$cuisines_array[] = $single;
}
}
}
dd($cuisines_array);
I want $cuisines_array to have something like
array:33 [▼
0 => "Afghani"
1 => "Mughlai"
2 => "Chinese"
3 => "Indian"
4 => "continental"
5 => "south indian"
6 => "mughlai"
But I am getting as in the screenshot: output screenshot
My Cuisines attribute in table is database table.
Any leads?
You can use array_slice() :
...
foreach (array_slice($array, 0, 6) as $single) {
...
array_slice()
returns the sequence of elements from the array array as specified by
the offset and length parameters

find out match word and display the position of it from the array values using php

I have a set of array data i need to find out the match word from that values of array
$my_word = 'mbusa.com';
$array_data = array:6 [
0 => array:2 [
0 => "Mercedes-Benz Luxury Cars: Sedans, SUVs, Coupes and Wagons"
1 => "/l/?kh=-1&uddg=https%3A%2F%2Fwww.mbusa.com%2Fmercedes%2Findex"
]
1 => array:2 [
0 => "Mercedes-Benz - International Corporate Website"
1 => "/l/?kh=-1&uddg=https%3A%2F%2Fwww.mercedes%2Dbenz.com%2F"
]
2 => array:2 [
0 => "New Mercedes-Benz Cars - Autotrader"
1 => "/l/?kh=-1&uddg=http%3A%2F%2Fwww.autotrader.com%2FMercedes%2BBenz%2Dcars.jsp"
]
3 => array:2 [
0 => "Mercedes-Benz C-Class - mbusa.com"
1 => "/l/?kh=-1&uddg=https%3A%2F%2Fwww.mbusa.com%2Fmercedes%2Fvehicles"
]
4 => array:2 [
0 => "Mercedes-Benz - New models: Pricing, MPG, and Ratings | Cars.com"
1 => "/l/?kh=-1&uddg=https%3A%2F%2Fwww.cars.com%2Fresearch%2Fmercedes_benz%2F"
]
5 => array:2 [
0 => "Mercedes-Benz Reviews - Mercedes-Benz Cars | Edmunds"
1 => "/l/?kh=-1&uddg=https%3A%2F%2Fwww.edmunds.com%2Fmercedes%2Dbenz%2F"
]
6 => array:2 [
0 => "Mercedes-Benz - Wikipedia"
1 => "/l/?kh=-1&uddg=https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FMercedes%2DBenz"
]
]
In this array , i need to find that my_word and need to display the position mbusa.com found at N position.
I m trying with the below code
$matches = array_filter($array_data, function($var) use ($my_word){
return preg_match("/\b$my_word\b/i", $var);
});
But it is giving error like
preg_match() expects parameter 2 to be string, array given
Any suggestions please ?
Thank you .
You can do it like below:-
foreach ($array_data as $key=>$val){
foreach ($val as $key1=>$v){
if(strpos($v,$my_word)!==false){
echo 'match position is $array_data['.$key."][".$key1."]";
echo PHP_EOL;
}
}
}
Output:- https://eval.in/745846
This way you can do this:
$count = 0;
for ($i = 0; $i < count($array_data); $i++) {
for ($j = 0; $j < count($array_data[$i]); $j++) {
if (strpos($array_data[$i][$j], 'mbusa') !== false) {
echo "Found at Postion ".$j."<br>";
echo $count++;
}
}
}
echo "Found " . $count . "Times";
You can use the strpos function which is used to find the occurrence of one string inside other:
$text = "/l/?kh=-1&uddg=https%3A%2F%2Fwww.mbusa.com%2Fmercedes%2Findex";
if (strpos($text, 'mbusa') !== false) {
echo 'true';
}

Categories