Uniq also produces a new array and returns it. It will simply return only 1 instance of each item in the array. So the array [4,5,6,7,4,3,25,6,5], would be returned as [4, 5, 6, 7, 3, 25].
Uniq will use each and indexOf.
var _ = {};
_.indexOf = function(array, target) {
// Although indexOf has been implemented for you, it has a DEPENDENCY: the
// iteration helper `each`, which you will need to write yourself (above).
var result = -1
_.each(array, function(item, index) {
if (item === target && result === -1) {
result = index
}
})
return result
}
_.each = function(collection, iterator){
if(Array.isArray(collection)){
for(var i = 0; i < collection.length; i ++){
iterator(collection[i], i, collection);
}
}
else{
for(var key in collection){
iterator(collection[key], key, collection);
}
}
}
_.uniq = function(array) {
var uniqArray = [];
_.each(array, function(item){
if(_.indexOf(uniqArray, item) === -1){
uniqArray.push(item);
}
})
return uniqArray;
}
And here's an alternative way of writing uniq:
_.uniq = function(array) {
var uniqueStorage = {};
var results = [];
_.each(array, function(item) {
uniqueStorage[item] = item;
});
_.each(uniqueStorage, function(prop) {
results.push(prop);
});
return results;
};
I'll begin by walking through the first uniq re write:
Since uniq will be returning a new array, I start by making a new local variable called uniqArray and set its value to an empty array.
Next I call each, feed it the array, and hard wire in a function, that takes item and then sets a conditional statement. Inside the if statement I call the value of indexOf with uniqArray as the array to be searched, and item as the target. Because it's empty, the first search of the array will return -1, which means that item does not exist inside that array. Then each will continue iterating through each item in the array, scanning uniqArray to see if that item is in there. If it is, indexOf will return the index value where the match is, and therefore it will not equal -1, and that item will not be pushed into uniqArray.
Finally, at the end of the function, uniqArray is returned.
Now, I'll walk through the second version.
First, two new local variables are created, uniqueStorage which is set as an empty object, and results which is set as an empty array.
Next, uniq calls each, feeds it the array, and then hard wires a function which takes an item, and then it creates a new property for uniqueStorage. The new property is the name of the item and its value is set to the same name of the item. Remember, how objects work. If you try to define another property with the same name and value, then it will simply overwrite the existing one, it will not make a new one.
For example, you could make an empty object named var emptyObject = {};
Then you can add some properties:
emptyObject[5] = 5;
emptyObject[5] = 5;
emptyObject[5] = 5;
console.log(emptyObject);
This is what will print to the console: {'5' : 5}
This is because the property 5 already exist, so it's simply overwriting the property that is already there.
Because of this, objects will often be used to filter out occurrences like this.
Next each is called once again, this time to run through the object, and it pulls all the values and pushes them to the new area to be returned.
Don't be fooled, in the above example, the word prop is used, but it is the value that is being called. Remember, in each in the for loop the first value provided is the value. You cannot simply call prop by name. If you use one parameter, you'll get the value, the second parameter will get you the property or the key, and the third parameter will be the collection itself.
I find the first rewrite to be easier, so I use that one myself.
No comments:
Post a Comment