megacolorboy

Abdush Shakoor's Weblog

Writings, experiments & ideas.

Find the difference between two arrays

Finding the difference between two sets i.e. Set A and Set B is basically returning a new set that contains values of Set A that don't exist in Set B or vice-versa.

Here's an example:

var a = [1,2,3,4,5];
var b = [1,1,2,3,4];

I wrote a shorter implementation using JavaScript's .filter() method:

function array_diff(a,b){
    return a.filter(i => b.indexOf(i) === -1);
}    

Once you execute this method, you'll get the following as a result:

var c = array_diff(a,b);
console.log(c) // returns [5]

BONUS: What does the .filter() method do?

This method returns a new array with elements that pass the conditions provided by a callback function.

If the conditions aren't passed, you'll receive an empty array.

In this article, (i => b.indexOf(i) === -1) is considered as the callback function in which the i refers to the index of the current element of array A and is then used as a parameter to check if the element doesn't exist in array B.

The neat thing about this method is that it doesn't mutate on the array that it's being called from.

Read more about Array.prototype.filter() on Mozilla's developer documentation.

How to duplicate tables in MySQL?

This trick comes in handy whenever you wanted to reuse a table, perform data migrations or maybe even take a backup of the table before any of your experiments mess up your data.

Executing the following query will help you create a new table with the structure of the old table:

CREATE TABLE schema.new_table LIKE schema.old_table;

If you want the data as well, try this:

CREATE TABLE schema.new_table LIKE schema.old_table;
INSERT schema.new_table SELECT * FROM schema.old_table;

You can use this query to copy tables from one schema to another schema too. Hope this helps you out! 😄

Find the number of uppercase and lowercase letters in a string

The usual approach of counting the number of uppercase and lower letters in a string is done by using a counter and a loop:

var upperCount = 0;
var lowerCount = 0;
var str = "AbCdEfGhiJkL";
for(var i=0; i<str.length; i++){
    if(str[i] == str[i].toUpperCase()){
        upperCount++;
    }
    else{
        lowerCount++;
    }
}

That's nice but here's shorter and faster implementation:

var str = "AbCdEfGhiJkL";
var lowerCount = str.length - str.replace(/[A-Z]/g, '').length;
var upperCount = str.length - str.replace(/[a-z]/g, '').length;

The lowerCount variable is taking the difference of the lengths between the original string and the string with lowercase letters only because the .replace() method replaced the pattern of uppercase letters [A-Z] with empty spaces. The upperCount variable does the opposite of what the lowerCount variable does.

Hope you found this trick useful!

Replace all occurrences found on a string using Regular Expressions

Let's say you have the following string and you must replace all occurrences of "Hello" with "Bye":

var str = "Hello Hello Hello World";

You may think of using the .replace() method to solve this problem:

var newStr = str.replace("Hello", "Bye")

But unfortunately, it only replaces the first occurrence in the string:

console.log(newStr); // returns "Bye Hello Hello World" as the output.

Using the power of Regular Expressions, you can replace all occurrences in one go:

function replaceAll(str, search, replace){
    var re = new RegExp(search, "g");
    return str.replace(re, replace);
}    

Now, when you execute the following, you'll get a string that replaced all occurrences:

var newStr = replaceAll(str, "Hello", "Bye");
console.log(newStr); // returns "Bye Bye Bye World" as the output.

Until next time, then!

Create a unique multidimensional array using a key index

Let's say, you have a multidimensional array like this:

<?php
$cars = [
    [
        "id" => 1,
        "name" => "Mercedes Benz",
        "color" => "Black"
    ],
    [
        "id" => 2,
        "name" => "Toyota",
        "color" => "Red"
    ],
    [
        "id" => 3,
        "name" => "Toyota",
        "color" => "White"
    ],
    [
        "id" => 4,
        "name" => "Nissan",
        "color" => "Grey"
    ],
];
?>

And say, you want to be able to return unique cars by name or color, use this method:

<?php
function multi_array_unique($array, $key) {
    $i = 0;
    $temp_array = [];
    $key_array = [];

    foreach($array as $val) {
        // insert only unique keys
        if (!in_array($val[$key], $key_array)) {
            $key_array[$i] = $val[$key];
            $temp_array[$i] = $val;
        }
        $i++;
    }
    return $temp_array;
}
?>

Call this method from anywhere in your code like this:

<?php
$unique_cars = multi_array_unique($cars, "name");
dd($unique_cars);
?>

And now, you'll get something like this:

<?php
[
    [
        "id" => 1,
        "name" => "Mercedes Benz",
        "color" => "Black"
    ],
    [
        "id" => 2,
        "name" => "Toyota",
        "color" => "Red"
    ],
    [
        "id" => 4,
        "name" => "Nissan",
        "color" => "Grey"
    ],
];
?>

You might wonder why I tried this instead of PHP's array_unique() method and the reason I didn't use it is because it doesn't support multidimensional arrays.

Hope you found this useful!

Extract YouTube Channel ID from URL

Using PHP's in-built function, parse_url, you can write a helper method to pull the channel ID off a YouTube URL especially if you're pulling videos using YouTube's Data API. Here's the code:

<?php
public function extractChannelID($url){
    // Parse the link and trim any whitespaces
    $parsed_link = parse_url(rtrim($url, '/'));

    // Return the channel ID if it matches the pattern
    if (isset($parsed_link['path']) && preg_match('/^\/channel\/(([^\/])+?)$/', $parsed_link['path'], $matches)) {
        return $matches[1];
    }

    throw new Exception("This {$url} is not a valid YouTube channel URL");
    return null;
}
?>

Writing tiny methods like these can help save time and be reusable in more than one context.

Hope you find this tip useful! 😁

Using zipcloak to encrypt files within an archive

Whenever you're sending a bunch of files or an archive that contains sensitive or confidential information, it's wise to encrypt before you send it to the person that you intend to.

Using zipcloak, you'll be able to encrypt files within your existing archive.

Do the following after you've created a zip archive:

zipcloak files.zip    

Now, you'll be prompted twice to enter a new password and verify your entered password. If they match, your archive will get encrypted. So whenever, you try to unzip or open using an Archive Manager, you'll be prompted to enter the password or else, you won't be able to access it.

You also have the choice of not encrypting the original archive and creating a new one instead, just like this:

zipcloak files.zip -O encrypted.zip    

On the other hand, if you do wish to remove the encryption from your archive, just type the following:

zipcloak -d files.zip

And you'll be prompted again to enter your password before it removes it's encryption.

Hope this helps you out! 😁

How to cache your queries on your Laravel application?

Although, Laravel is a good framework, it's quite heavy when it comes to executing queries especially if you're using the Eloquent ORM instead of the normal query builder.

But Laravel does offer the option of caching your queries in the server and will only make calls to your database if there's a change in content.

Quite handy when you're having a content-heavy website and huge amount of user traffic.

Using the Cache class, you can cache your queries like this:

<?php
$apples = \Cache::rememberForever('apples_cache', function(){
    return FruitsModel::where('item_name', 'LIKE', '%apples')
        ->get();
});
?>

In the above example, apples_cache is the key that stores your queries of apples forever and which will be used to obtain your cached results from the server.

Oh, be sure to create distinctive names for different types of queries or else, you'll end up being confused! 😜

You can also give it a time limit in milliseconds:

<?php
$apples = \Cache::remember('apples_cache', 300000, function(){
    return FruitsModel::where('item_name', 'LIKE', '%apples')
        ->get();
});
?>

Hope this tip helps you out! 😀