loading...
Cover image for Essential Vanilla JavaScript Functions

Essential Vanilla JavaScript Functions

amit_merchant profile image Amit Merchant ・4 min read

Essential Vanilla JavaScript Functions

Some of the missing functions in JavaScript in vanilla form (inspired by PHP). You can just try it as a programming practice.

Array Functions

array_unique()

Remove duplicates from an array

function array_unique(arr){
    var seen = {};
    var ret_arr = [];
    var key;
    var i;

    function keyify(obj){
        var ret = "";
        var j;

        if (Object.prototype.toString.call(obj) === "[object Object]" || Object.prototype.toString.call(obj) === "[object Array]"){
            for (j in obj){
                ret += "~" + j + "^" + keyify(obj[j]) + "%";
            }
            return ret;
        }else{
          return obj;
        }
    }

    for(i = 0; i < arr.length; i++){
        key = keyify(arr[i]);
        if(!(key in seen)){
            ret_arr.push(arr[i]);
            seen[key] = true;
        }
    }

    return ret_arr;
}

array_unique([4,5,4,6,7,8,2,6]);
// [4, 5, 6, 7, 8, 2]
array_unique([{a: 'val'}, {b: 'val', c: 'val'}, 'a', 'b', [1,2,3,4], {a: 'val'}, [1,2,3,4], [{a: 'val'}, {b: 'val'}], [{a: 'val'}, {b: 'val'}]]);
// [{a: 'val'}, {b: 'val', c: 'val'}, 'a', 'b', [1,2,3,4], [{a: 'val'}, {b: 'val'}]]

array_merge()

Merge two arrays

function array_merge(arr1, arr2){
    for(var i=0; i<arr2.length; i++){
        arr1.push(arr2[i]);
    }

    return arr1;
}

array_merge([1, 2, 3], [4, 5]);
// [1, 2, 3, 4, 5]

array_chunk()

Splits an array into chunks of arrays

function array_chunk(arr, count){
    var temp_arr = [];

    for(var i=0; i<arr.length;){
        var chunk_arr = [];
        for(var j=0; j<count; j++){
            if(!arr[i])
                break;
            chunk_arr.push(arr[i]);
            i++;
        }
        temp_arr.push(chunk_arr);
    }

    return temp_arr;
}

array_chunk([1,2,3,4,5,6,7,8,9], 4);
// [ [ 1, 2, 3, 4 ], [ 5, 6, 7, 8 ], [ 9 ] ]

array_collapse()

Collapses a collection of arrays into a single, flat array


function array_collapse(...arrays){
    var collapse_arr = [];

    for(var i=0; i<arrays.length;i++){
        for(var j=0; j<arrays[i].length; j++){
            collapse_arr.push(arrays[i][j]);
        }
    }

    return collapse_arr;
}

array_collapse([1, 2, 3, 4], [5, 6], ["hello", "world"]);
// [ 1, 2, 3, 4, 5, 6, 'hello', 'world' ]

array_diff()

Returns the values in the arr1 that are not present in arr2

function array_diff(arr1, arr2){
    var temp_arr = [];

    for(var i=0; i<arr1.length; i++){
        if(arr2.indexOf(arr1[i]) == -1){  
            temp_arr.push(arr1[i]);
        }
    }

    return temp_arr;
}

array_diff([4,5,6,7, "unicorn"], [5, 6, 7]);
// [ 4, 'unicorn' ]

array_intersect()

Returns the values common in the two supplied arrays

function array_intersect(arr1, arr2){
    var temp_arr = [];

    for(var i=0; i<arr1.length; i++){
        if(arr2.indexOf(arr1[i]) != -1){  
            temp_arr.push(arr1[i]);
        }
    }

    return temp_arr;
}

array_intersect([4,5,6,7, "unicorn"], [5, 6, 7, 8]);
// [ 5, 6, 7 ]

array_map()

Sends each value of an array to a user-made function, which returns new values

function array_map(arr, func){
    var temp_arr = [];

    if(typeof func !== "function")
        throw "Second parameter should be a function";

    for(var i=0; i<arr.length; i++){
        temp_arr.push(func(arr[i]));
    }

    return temp_arr;
}

array_map([1, 2, 3, 4, 5], function (value) {
    return value * 2;
});
// [ 2, 4, 6, 8, 10 ]

array_reject()

Filters the array using the given callback. The callback should return true if the item should be removed from the resulting array

function array_reject(arr, func){
    var temp_arr = [];

    if(typeof func !== "function")
        throw "Second parameter should be a function";

    for(var i=0; i<arr.length; i++){
        if(func(arr[i]))
            temp_arr.push(arr[i]);
    }

    return temp_arr;
}

array_reject([1, 2, 3, 4, 5], function (value) {
    return value > 3;
});
// [ 4, 5 ]

array_split()

Breaks an array into the given number of groups

function array_split(arr, count){
    var temp_arr = [];
    var arr_length = arr.length;

    var chunk = Math.floor(arr_length/count);

    for(var i=0; i<arr.length;){
        var chunk_arr = [];

        if(temp_arr.length == (count-1))
            chunk = chunk + (arr_length-i);

        for(var j=0; j<chunk; j++){
            if(!arr[i])
                break;
            chunk_arr.push(arr[i]);
            i++;
        }

        temp_arr.push(chunk_arr);
    }

    return temp_arr;
}

array_split([1,2,3,4,5,6,7,8,9], 4);
// [ [ 1, 2 ], [ 3, 4 ], [ 5, 6 ], [ 7, 8, 9 ] ]

array_take()

Returns a new array with the specified number of items

function array_take(arr, count){
    var temp_arr = [];

    if(count<0){
        count = Math.abs(count);
        for(var i=(arr.length-count); i<arr.length; i++){
            temp_arr.push(arr[i]);
        }
    }else{
        for(var i=0; i<count; i++){
            temp_arr.push(arr[i]);
        }
    }

    return temp_arr;
}

array_take([1,2,3,4,5,6,7,8,9], 4);
// [ 1, 2, 3, 4 ]

You may also pass a negative integer to take the specified amount of items from the end of the array:

array_take([1,2,3,4,5,6,7,8,9], -3);
// [ 7, 8, 9 ]

array_pad()

Inserts a specified number of items, with a specified value, to an array


function array_pad(arr, size, value){
    for(var i=0; i<size; i++){
        arr.push(value);
    }
    return arr;
}

array_pad([1,2,3,4], 2, "unicorn");
// [ 1, 2, 3, 4, 'unicorn', 'unicorn' ]

range()

Creates an array containing a range of elements

function range(start, end){
    var temp_arr = [];

    for(var i=start; i<=end; i++){
        temp_arr.push(i);
    }

    return temp_arr;
}

range(5, 11);
// [ 5, 6, 7, 8, 9, 10, 11 ]

String Functions

chunk_split()

Splits a string into a series of smaller parts

function chunk_split(string, length, end){
    var temp_string = '';

    for(var i=0; i<string.length; i++){
        temp_string += string[i];
        if((i+1)%length==0)
            temp_string += end;
    }

    return temp_string;
}

console.log(chunk_split("Hello", 1 , "."));
// H.e.l.l.o.
console.log(chunk_split("Hello", 1 , ".."));
// H..e..l..l..o..

str_pad()

Pads a string to a new length

function str_pad(string, size, value){
    for(var i=0; i<size; i++){
        string += value;
    }

    return string;
}

str_pad("unicorn", 5 , ".");
// unicorn.....

strrev()

Reverses a string

function strrev(string){
    var temp_string = '';

    for(var i=string.length-1; i>=0; i--){
        temp_string += string[i];
    }

    return temp_string;
}

strrev("unicorn");
// nrocinu

similar_text()

Calculates the similarity between two strings

function similar_text(string1, string2){
    var seen = {};
    var similar_count = 0;

    for(var i=0; i<string1.length; i++){
        if((string2.indexOf(string1[i]) !== -1 && !(string1[i] in seen)) 
                || string1[i]==' ')
        {
            similar_count++;
            if(string1[i]!='')
                seen[string1[i]] = true;
        }
    }

    return similar_count;
}

similar_text("Hello World","Hello Peter");
// 6

Originally published at amitmerchant1990/essential-vanilla-javascript-functions.

Posted on Jun 12 '17 by:

amit_merchant profile

Amit Merchant

@amit_merchant

Coder, thinker and an aspiring entrepreneur.

Discussion

markdown guide
 

Super handy utilities! As a sorta-wannabe-functional programmer, though, the implementations of some of them are a bit scary to me (loops, mutation, and stuff). For anyone looking for less imperative versions, here are some of them:

const unique = (arr) => [ ...new Set(arr) ]
const merge = (a, b) => a.concat(b)
const collapse = (a) => Array.isArray(a) ? [].concat(...a.map(arrayCollapse)) : a
const intersect = (a, b) => [ ...new Set(a.filter((e) => b.includes(e))) ]
const map = (a, f) => a.map(f)
const reject = (a, f) => a.filter(f)
const take = (a, n) => n > a.length ? a : a.slice(0, n)
 

Interesting approach for array_unique (even taking into account that objects and arrays in the array might have different pointers, but have the same content. There's just one minor issue: x in y will also return true for the constructor attribute, so better use y.hasOwnProperty(x). If your array contains 'constructor' as a string, your function will filter it out.

 

Yeah. We can implement it that way as well. If you want you can send over a pull request on github.com/amitmerchant1990/essent...

 
 

Sorry, but while the big majority of these functions are pretty useless (you might find them in lodash or even in the language itself), the implementations show a big misunderstanding of how JavaScript works.
You can do pretty much anything with Array functions like map, reduce, filter, slice and concat. They are helpful because they do not mutate the original array, but produce a new one.
And finally, it is really not necessary to pollute your code with such ugly names, even if PHP provides them. Next readers won't necessary know a lot about PHP.

 

This, and you can even use the ...spread operator instead of concat, to create a new array from an existing one.
The above functions are translated a bit too literally from PHP, or perhaps the intention was to make them work for ES5 / lower?

 

Why are map, reject and taken part of your list (they already exist in vanilla JS)? When (besides an job interview) did you have the need for strrev?
Besides that a very nice exercise.

 

Pardon me for that. I was curious and was just trying to do my implementation.

 

Gotta give a shout out to Locutus here, a source for hundreds of Javascript implementations of PHP functions (and other languages).

 

I love what you have done. Keep it up. The raised point on mutation is a good one. These need to process cloned objects not original. With regard these (map, reduce, filter, slice and concat), blind use of these is as good as blind use of frameworks.

 

Neat! I love doing things in Vanilla JavaScript over including a big library whenever I can. However, to make the code a bit nicer I'd suggest adding the array and string methods to their actual object prototypes if possible. In my opinion it makes the code look much nicer and is a convenience Javascript has the original PHP functions do not. (That's the reason PHP has so many functions that start with "array" or "string")

 

Awesome utilities, just one question, what is this line for?

ret += "~" + j + "^" + keyify(obj[j]) + "%";

Why do you use "~", ^ and "%"?

 
 

Yes! This is exactly what I needed. As a PHP developer I always use those functions. Thank you.