Duplicate-free version of array of objects - javascript

I implemented a function that creates a duplicate-free version of an array, but it doesn't work for array of objects. I don't understand and I can't find information how to fix it.
My function:
function uniq(array) {
var length = array.length;
if (!length) {
return;
}
var index = 0;
var result = [];
while (index < length) {
var current = array[index];
if (result.indexOf(current) < 0) {
result.push(current);
}
index++;
}
return result;
}
Example:
var my_data = [
{
"first_name":"Bob",
"last_name":"Napkin"
},
{
"first_name":"Billy",
"last_name":"Joe"
},
{
"first_name":"Billy",
"last_name":"Joe",
}
]
uniq([1, 1, 2, 3]) // => [1, 2, 3]
uniq(my_data) // => [ { "first_name":"Bob", "last_name":"Napkin" }, { "first_name":"Billy", "last_name":"Joe" }, { "first_name":"Billy", "last_name":"Joe" } ]
Do you know someone how to creates a duplicate-free version of array of objects?

indexOf() in javascript does not perform a deep comparison of objects. On top of that, any two objects that are created will never be "equal" to each other. If you do:
var a = {};
var b = {};
a == b; //false
a === b; //false
You need to perform a deep comparison against all values (if that's even what you're looking to do, because there could be other equalities you're looking for). I won't go into how to do a deep comparison because, well, Google.

A solution if the objects are not huge, the array doesn't have a huge amount of elements and if the objects don't contain reference loops is to use JSON.stringify to decide if two objects are equal...
function uniq(A) {
var seen = {};
var result = [];
A.forEach(function(x) {
var str = "" + JSON.stringify(x);
if (!seen[str]) {
seen[str] = 1;
result.push(x);
}
});
return result;
}

Since these objects are simply used for data storage (i.e. they don't have methods or prototype extensions and such applied to them), I might suggest serializing and hashing each object in the array and storing the hashes in an object for determination of uniqueness. Now the question is which hashing function to use. There are a number of md5 and SHA-256 implementations available (search StackOverflow for this). My example will just assume the existence of a hash function called hashFunction().
function uniqArrayObjects(array) {
// make sure we have an array
if(Array.isArray(array) === false) {
console.log('Doh! No array passed.');
return null;
}
var length = array.length;
// you can return input array if it has 0 or 1 items in it
// it is already unique
if (length === 0 || length === 1) {
return array;
}
// object for storing hashes
var hashTable = {};
// filter and return the array
return array.filter(function(obj) {
var json = JSON.stringify(obj);
var hash = hashFunction(json);
if (typeof hashTable[hash] === undefined) {
// this item doesn't exist in hash table yet
// add to hash table and return true to add this to filtered result
hashTable[hash] = 1; // value doesn't matter here
return true;
} else {
return false;
}
});
}

Related

return object if list<object> value is exists (Javascript, jquery grep/map)

I'm using grep and map functions to get the object if the value is exists in the list, but it does not work well.
I have a list customList and the customObject has the int id property and List value properties.
customobject[0].id
customObject[0].value[]
What I want is check if in the List the value 5 exists.
The function what I'm using is:
var gettedcustomObject = $.grep(customList, function (e) {
var result = e.Value.map(function (a) { return a === 5;});
return result;
});
What am I doing wrong and what is the correct implementation?
Note: 2x foreach could be a solution, but customList has more than 1000 objects with 10000 values. I think that slow down the proces.
This should do it.
var gettedcustomObject = customList.filter(function(v){
var ln = v.Value.length;
for(var i = 0; i < ln; i++){
if(v.Value[i] == 5){
return true;
}
}
return false;
// Or simply:
// return v.Value.indexOf(5) != -1;
});
This will work if v.Value is an array.
You should look at some: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some#Polyfill
Way faster than the other methods like filter, map or sort as it was designed for this.
//List to work against
var arr = [];
//Populate
while (arr.length < 9999999) {
arr.push(Math.random() * 999999)
}
//Set element to find
arr[10] = "test";
//Begin timing
var d = new Date().getTime();
//Run filter
console.log(arr.filter(function(a){return a === "test"}).length > 0);
//How long did it take
console.log("`filter` took:",new Date().getTime() - d,"ms")
//Begin timing
d = new Date().getTime();
//Run filter
console.log(arr.some(function(a){return a === "test"}));
//How long did it take
console.log("`some` took:",new Date().getTime() - d,"ms")
<script>
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some#Polyfill
// Production steps of ECMA-262, Edition 5, 15.4.4.17
// Reference: http://es5.github.io/#x15.4.4.17
if (!Array.prototype.some) {
Array.prototype.some = function(fun/*, thisArg*/) {
'use strict';
if (this == null) {
throw new TypeError('Array.prototype.some called on null or undefined');
}
if (typeof fun !== 'function') {
throw new TypeError();
}
var t = Object(this);
var len = t.length >>> 0;
var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
for (var i = 0; i < len; i++) {
if (i in t && fun.call(thisArg, t[i], i, t)) {
return true;
}
}
return false;
};
}
</script>
If your goal is to find the first object in the list that contains 5 in the Value property, then you're looking for Array#find and Array#indexOf:
var gettedcustomObject = customList.find(function(entry) {
return entry.Value.indexOf(5) != -1;
});
Note that Array#find was added relatively recently and so you may need a polyfill for it (which is trivial). MDN has one.
Or you could use Array#includes instead of indexOf, which will be in ES2017 and is also polyfillable:
var gettedcustomObject = customList.find(function(entry) {
return entry.Value.includes(5);
});
Live Example (using indexOf):
var customList = [
{
note: "I'm not a match",
Value: [2, 3, 4]
},
{
note: "I'm not a match either",
Value: [78, 4, 27]
},
{
note: "I'm a match",
Value: [889, 5, 27]
},
{
note: "I'm also a match, but you won't find me",
Value: [4, 6, 5]
}
];
var gettedcustomObject = customList.find(function(entry) {
return entry.Value.indexOf(5) != -1;
});
console.log(gettedcustomObject);
If your logic matching the item inside Value were more complicated, you'd use Array#some and a callback function rathe than indexOf. But when looking to see if an array for an entry in an array based on ===, indexOf or the new Array#includes are the way to go.
one approach using Array.some() and Array.indexOf(). some loop break once the element is found
var gettedcustomObject;
customobject.some(function(obj){
if(obj.value.indexOf(5) >-1){
gettedcustomObject = obj;
return true;
}
});

Word frequency for array of key/values on javascript

I'm trying to implement a piece of code on javascript to analyse word/frequency on a given string. My objective is to return a array as the following:
[{text: firstword, size:3 },{text:secondword , size:5 },{text: nword, size: 1},...]
I implemented the following code but I'm running out of memory, so I don't really know if its ok or not.
function wordFrequency(txt){
var wordArray = txt.split(/[ .?!,*'"]/);
var newArray = [];
$.each(wordArray, function (ix, word) {
if (newArray.length >= 1){
newArray.some(function (w){
if (w.text === word){
w.size++;
} else {
newArray.push({text: word, size: 1});
}
});
} else {
newArray.push({text: word, size: 1});
}
});
return newArray;
}
Array.prototype.some expects the given callback to return true or false and returns true as soon as your callback returns true for a given element, otherwise it returns false.
So some iterates over all elements, with your given callback, and your callback checks if the given element text equals the search word and if not adds a new object. Introducing a new element the some function can iterate over.
So to make this clear, for every word thats in the newArray before the word you're searching, you're adding a new object containing your word.
Suppose your newArray looks like this:
[{word:"test"},{word:"another"},{word:"one"},{word:"more"}]
after calling your function for the word even it looks like this:
[{word:"test"},{word:"another"},{word:"one"},{word:"more"},{word:"even"},{word:"even"},{word:"even"},{word:"even"}]
Using Array.prototype.filter would be the better approach here, finding you the matching element, note that I also replaced $.each with Array.prototype.forEach:
function wordFrequency(txt){
var wordArray = txt.split(/[ .?!,*'"]/);
var newArray = [], wordObj;
wordArray.forEach(function (word) {
wordObj = newArray.filter(function (w){
return w.text == word;
});
if (wordObj.length) {
wordObj[0].size += 1;
} else {
newArray.push({text: word, size: 1});
}
});
return newArray;
}
document.write(JSON.stringify(wordFrequency("count everything, count all the words, count all the words!").sort(function(a,b){return a.size<b.size})).split("},").join("}<br/>"));
It would be simpler and far more efficient to create a direct map from word to frequency, and only afterwards convert that to your array structure. Given an array words create a map of the words:
var freq = words.reduce(function(p, c) {
p[c] = (p[c] || 0) + 1;
return p;
}, {});
and the convert that map into your array:
var array = Object.keys(freq).map(function(key) {
return { text: key, size: freq[key] };
});
To tell the frequency all you need is a hash map approach. Your algorithm is quadratic, since the some method is nested in the each method, so you're always looping over the newArray just to find an entry and increment the size.
A map approach is easily achievable using a JavaScript object. It also gives you constant look-up time, which is better performance than the nested loops approach.
Try this approach instead:
function wordFrequency(txt){
var wordArray = txt.split(/[ .?!,*'"]/);
var map = {};
$.each(wordArray, function(ix, word) {
// skip empty results
if (!word.length) {
return;
}
// add word to map
if (!map[word]) {
map[word] = 0;
}
map[word]++;
});
return map;
}
To use the function:
var text = "hello!world*hello foo 'bar'foo";
var result = wordFrequency(text);
// iterate over results
Object.keys(result).forEach(function(w) {
console.log(w + ": " + result[w]);
});
// or use for...in
for (var w in result) {
console.log(w + ": " + result[w]);
}
If you really wanted to, you could then map the result into your desired array format with text and size properties:
var mappedResult = Object.keys(result).map(function(w) {
return { text: w, size: result[w] };
});
console.log(mappedResult);
Also, depending on your target browsers, you might consider using the array forEach instead of the jQuery $.each, similar to what I did with the Object.keys portion.
Here's the JSBin example.
You would probably want to avoid any iterations on duplicate elements and keep your results array unique. Since any of the iterators of Array.prototype will include each of the elements, they might not be the ideal solution for this. Sometimes plain old loops do the job best ...
(You may also want to expressively escape any special characters in your regular expression).
function wordFrequency(txt) {
var words = txt.split(/[ \.\?!,\*'"]+/),
seen = [];
for (var i = 0; i < words.length; i++) {
var w = words[i],
found = false;
for (var j = 0; j < seen.length; j++) {
if (w === seen[j].text) {
seen[j].size++;
found = true;
break;
}
}
if (!found) seen.push( { text: w, size: 1 } );
}
return seen;
}
(Note that the inner for-loop isn't visited for the first word, so the first word will be pushed to the seen-stack and the inner for-loop will start with the second word compared to the first one. Only words that we haven't seen already are added to the seen-stack, making it an array of unique elements.)
And here is the equivalent using Array.prototype.forEach() and Array.prototype.indexOf(), but we have to add another intermediate results stack for the latter one. So we'll have to add another iteration to produce the final result. (We wouldn't have to do this using Array.prototype.findIndex(), but this is not a standard method.)
function wordFrequency2(txt) {
var words = txt.split(/[ \.\?!,\*'"]+/),
seen = [],
freq = [];
// get frequencies
words.forEach(function (w) {
var idx = seen.indexOf(w);
if (idx >= 0) {
freq[idx]++;
}
else {
seen.push(w);
freq.push(1);
}
});
// produce the results array
var r = [];
seen.forEach(function (w, idx) {
r.push( { text: w, size: freq[idx] } );
});
return r;
}
Putting optimization into account, the first version using explicit loops will be probably performing faster ...
var words = (function(){
var sWords = document.body.innerText.toLowerCase().trim().replace(/[,;.]/g,'').split(/[\s\/]+/g).sort();
var iWordsCount = sWords.length; // count w/ duplicates
// array of words to ignore
var ignore = ['and','the','to','a','of','for','as','i','with','it','is','on','that','this','can','in','be','has','if'];
ignore = (function(){
var o = {}; // object prop checking > in array checking
var iCount = ignore.length;
for (var i=0;i<iCount;i++){
o[ignore[i]] = true;
}
return o;
}());
var counts = {}; // object for math
for (var i=0; i<iWordsCount; i++) {
var sWord = sWords[i];
if (!ignore[sWord]) {
counts[sWord] = counts[sWord] || 0;
counts[sWord]++;
}
}
var arr = []; // an array of objects to return
for (sWord in counts) {
arr.push({
text: sWord,
frequency: counts[sWord]
});
}
// sort array by descending frequency | http://stackoverflow.com/a/8837505
return arr.sort(function(a,b){
return (a.frequency > b.frequency) ? -1 : ((a.frequency < b.frequency) ? 1 : 0);
});
}());
(function(){
var iWordsCount = words.length; // count w/o duplicates
for (var i=0; i<iWordsCount; i++) {
var word = words[i];
console.log(word.frequency, word.text);
}
}());

Get full value from array using partial value

I have an array like this:
var array = ["xs-1", "sm-10", "md-4"];
Now I want to get the number at the end of a particular value. For example I want to search the array for "md-" and see what number is at the end of that string (should return 4).
I can't do array.indexOf("xs-") because that isn't the whole value. Is there a way to do this?
Using a for loop:
var array = ["xs-1", "sm-10", "md-4"];
var search = "md-";
var found = null;
for (var i = 0; i < array.length; i++) {
if (array[i].indexOf(search) === 0) {
found = array[i];
break; // Note: this is assuming only one match exists - or at least you are
// only interested in the first match
}
}
if (found) {
alert(found);
} else {
alert("Not found");
}
Using .filter:
var array = ["xs-1", "sm-10", "md-4"];
var search = "md-";
var filtered = array.filter(function(item) {
return item.indexOf(search) === 0;
});
// note that here filtered will contain all matched elements, so it might be more than
// one match.
alert(filtered);
Building from #János Weisz's suggestion, you can easily transform your array into an object using .reduce:
var array = ["xs-1", "sm-10", "md-4"];
var search = "md";
var obj = array.reduce(function(prev, item) {
var cells = item.split("-");
prev[cells[0]] = cells[1];
return prev;
}, {});
// note: at this point we have an object that looks like this:
// { xs:1, sm:10, md: 4 }
// if we save this object, we can do lookups much faster than looping
// through an array
// now to find "md", we simply do:
alert(obj[search]);
If you need to do multiple look ups from the same source array, then transforming it into an object may be the most efficient approach overall. You pay the initial price of the transformation, but after than lookups are O(1) versus O(n) for each time you have to search your array. Of course, if you only ever need one item, then probably don't bother.
I recommend using objects for this:
var array = [{'type': 'xs', 'value': 1}, {'type' : 'sm', 'value': '10'}, {'type' : 'md', 'value': '4'}];
This way you can search the array as:
function searchMyArrayByType(array, type) {
var items[];
for (var i = 0; i < array.length; i++)
{
if (array[i].type == type) items.push(array[i].value);
}
return items;
}
var valuesWithMd = searchMyArrayByType(array, 'md');
For more information regarding the structure and use of objects, please refer to https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects
You can create a method that takes the prefix you're looking for, the array, and the split character and returns all the numbers in an array:
function findNumberFromPrefix(prefix, arr, splitChar) {
var values = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i].indexOf(prefix) === 0) {
values.push(arr[i].split(splitChar)[1]);
}
}
return values;
}
And call it:
var array = ["xs-1", "sm-10", "md-4"];
var values = findNumberFromPrefix("md-", array, "-");
console.log(values); //["4"]
Demo: http://jsfiddle.net/rn4h9msh/
A more functional approach and assuming you can have have more than one element with the same prefix:
function findPrefix(array, prefix) {
return array.filter(function (a) { return a.indexOf(prefix) === 0; })
.map(function (e) { return e.slice(prefix.length); })
}
If you have only one matching element, do a loop like this:
var array = ["xs-1", "sm-10", "md-4"];
var needle = "md-";
for(i=0;i<array.length;i++) {
if(array[i].indexOf(needle) == 0)
alert(array[i].substr(needle.length, array[i].length));
}
Demo: http://jsfiddle.net/kg0c43ov/
You can do it like this...
var array = ["xs-1", "sm-10", "md-4"];
getValue("md-");
function getValue(search) {
for(var key in array) {
if(array[key].indexOf(search) > -1) {
alert("Array key is: " + key);
alert("Array value is: " + array[key].replace(search, ""));
}
}
}
JSFiddle here.

Count unique elements in array without sorting

In JavaScript the following will find the number of elements in the array. Assuming there to be a minimum of one element in the array
arr = ["jam", "beef", "cream", "jam"]
arr.sort();
var count = 1;
var results = "";
for (var i = 0; i < arr.length; i++)
{
if (arr[i] == arr[i+1])
{
count +=1;
}
else
{
results += arr[i] + " --> " + count + " times\n" ;
count=1;
}
}
Is it possible to do this without using sort() or without mutating the array in any way? I would imagine that the array would have to be re-created and then sort could be done on the newly created array, but I want to know what's the best way without sorting.
And yes, I'm an artist, not a programmer, your honour.
The fast way to do this is with a new Set() object.
Sets are awesome and we should use them more often. They are fast, and supported by Chrome, Firefox, Microsoft Edge, and node.js.
— What is faster Set or Object? by Andrei Kashcha
The items in a Set will always be unique, as it only keeps one copy of each value you put in. Here's a function that uses this property:
function countUnique(iterable) {
return new Set(iterable).size;
}
console.log(countUnique('banana')); //=> 3
console.log(countUnique([5,6,5,6])); //=> 2
console.log(countUnique([window, document, window])); //=> 2
This can be used to count the items in any iterable (including an Array, String, TypedArray, and arguments object).
A quick way to do this is to copy the unique elements into an Object.
var counts = {};
for (var i = 0; i < arr.length; i++) {
counts[arr[i]] = 1 + (counts[arr[i]] || 0);
}
When this loop is complete the counts object will have the count of each distinct element of the array.
Why not something like:
var arr = ["jam", "beef", "cream", "jam"]
var uniqs = arr.reduce((acc, val) => {
acc[val] = acc[val] === undefined ? 1 : acc[val] += 1;
return acc;
}, {});
console.log(uniqs)
Pure Javascript, runs in O(n). Doesn't consume much space either unless your number of unique values equals number of elements (all the elements are unique).
Same as this solution, but less code.
let counts = {};
arr.forEach(el => counts[el] = 1 + (counts[el] || 0))
This expression gives you all the unique elements in the array without mutating it:
arr.filter(function(v,i) { return i==arr.lastIndexOf(v); })
You can chain it with this expression to build your string of results without sorting:
.forEach(function(v) {
results+=v+" --> " + arr.filter(function(w){return w==v;}).length + " times\n";
});
In the first case the filter takes only includes the last of each specific element; in the second case the filter includes all the elements of that type, and .length gives the count.
This answer is for Beginners. Try this method you can solve this problem easily. You can find a full lesson for reduce, filter, map functions from This link.
const user = [1, 2, 2, 4, 8, 3, 3, 6, 5, 4, 8, 8];
const output = user.reduce(function (acc, curr) {
if (acc[curr]) {
acc[curr] = ++acc[curr];
} else {
acc[curr] = 1;
}
return acc;
}, {});
console.log(output);
function reomveDuplicates(array){
var newarray = array.filter( (value, key)=>{
return array.indexOf(value) == key
});
console.log("newarray", newarray);
}
reomveDuplicates([1,2,5,2,1,8]);
Using hash Map with the time complexity O(n)
function reomveDuplicates(array){
var obj ={};
let res=[];
for( arg of array){
obj[arg] = true;
}
console.log(Object.keys(obj));
for(key in obj){
res.push(Number(key)); // Only if you want in Number
}
console.log(res);
}
reomveDuplicates([1,2,5,2,1,8]);
In a modern, extensible and easy-to-read approach, here's one using iter-ops library:
import {pipe, distinct, count} from 'iter-ops';
const arr = ['jam', 'beef', 'cream', 'jam'];
const count = pipe(arr, distinct(), count()).first;
console.log(count); //=> 3
function check(arr) {
var count = 0;
for (var ele of arr) {
if (typeof arr[ele] !== typeof (arr[ele+1])) {
count++;
} else {
("I don't know");
}
}
return count;
}

What are your favorite Mootools/Prototype native object prototypes? [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
Us Mootoolers and Prototypers (what few are on this site) usually carry around a handy toolbox of functions we have created (or borrowed) that we implement on native javascript objects to make our lives a little easier. I wanted get a list together of very helpful prototyped functions, but only ones that are implemented on native objects (ie String.implement({... in mootools).
So, what are your favorites?
PS: I included both mootools and prototype as a function written for one library is pretty easily ported to the other.
PPS: I know the arguments for/against prototyping native javascript objects, I would prefer to avoid that discussion here.
I continued on what tj111 started, here's my small addition:
Array.implement({
//calculate the sum of all integers
sum: function() {
var sum = this.reduce(function(a, b) {
return a + b;
});
return sum;
}
});
Here are some of my favorites for mootools.
String functions
String.implement({
//easy way to test if a string contains characters (input.value.isEmpty())
isEmpty : function() {
return (!this.test(/\w+/));
},
//add ellipses if string length > len
ellipse : function(len) {
return (this.length > len) ? this.substr(0, len) + "..." : this;
},
//finds all indexOf occurrences
indexesOf : function(val) {
var from = 0;
var indexes = [];
while (0 <= from && from < this.length) {
var idx = this.indexOf(val, from);
if (idx >= 0) {
indexes.push(idx);
} else {
break;
}
from = idx+1;
}
return indexes;
}
});
Array functions
Array.implement({
//compare two arrays to see if they are identical
compare : function(arr, strict) {
strict = strict || false;
if (this.length != arr.length) return false;
for (var i = 0; i < this.length; i++) {
if ($type(this[i]) == "array") {
if (!this[i].compare(arr[i])) return false;
}
if (strict) {
if (this[i] !== arr[i]) return false;
} else {
if (this[i] != arr[i]) return false;
}
}
return true;
},
//remove non-unique array values
unique : function() {
for(var i = 0; i< this.length; i++) {
var keys = this.indexesOf(this[i]);
while (keys.length > 1) {
this.splice(keys.pop(), 1);
}
}
return this;
},
//same as array.unshift, except returns array instead of count
//good for using inline... array.lpush('value').doSomethingElse()
lpush : function() {
for (var i = arguments.length -1 ; i >= 0; i--){
this.unshift(arguments[i]);
}
return this;
},
//get all indexes of an item in an array
indexesOf : function(item) {
var ret = [];
for (var i = 0; i < this.length; i++) {
if (this[i] == item) ret.push(i);
}
return ret;
}
});
//taken from http://prototype.lighthouseapp.com/projects/8886/tickets/351-new-swap-method-for-elements
Element.addMethods({
swap: (function() {
if ('swapNode' in document.documentElement)
return function(element, other) {
return $(element).swapNode($(other));
};
return function(element, other) {
element = $(element);
other = $(other);
var next = other.nextSibling, parent = other.parentNode;
element.parentNode.replaceChild(other, element);
return parent.insertBefore(element, next);
};
})()
});
// extend the array object to support indexed insertions
// submitted at http://prototype.lighthouseapp.com/projects/8886-prototype/tickets/356-arrayinsert
Array.prototype.insert=function(element,where) {
var slice1=this.slice(0,where);
var slice2=this.slice(where);
return new Array.concat(slice1,element,slice2);
};
//extend the array object to support searching thrtough indexed arrays
// if returnIndex is true, then return the keyName, else return the value from that cell
Array.prototype.nextValue=function(startIndex,returnIndex) {
for(var i=startIndex+1;i<this.length;i++){
if(this[i]){
return (returnIndex?i:this[i]);
}
}
return null;
};
//extend the array object to support searching thrtough indexed arrays
// if returnIndex is true, then return the keyName, else return the value from that cell
Array.prototype.prevValue=function(startIndex,returnIndex) {
for(var i=startIndex-1;i>=0;i--){
if(this[i]){
return (returnIndex?i:this[i]);
}
}
return null;
};
I haven't really been developing with neither Prototype nor Mootools, but I guess the following things would be useful in those frameworks too.
Replacement for native Math.round() that takes optional second parameter that specifies the precision:
Math.round(3.1415, 2); // 3.14
not() method for functions to get a negated predicate:
var even = function(x){ return x % 2 === 0; };
var odd = even.not();
even(2); // true
odd(2); // false
But most useful things are the ones, that I would add to Object.prototype if that would be a safe way to do it, so instead I have some global functions to iterate over object properties.
objMap() that works like Array.map() but for objects:
// returns {a:2, b:4, c:6}
objMap({a:1, b:2, c:3}, function(value) {
return value*2;
});
objValues() and objKeys() to get array of property names or values from object:
objValues({a:1, b:2, c:3}); // [1, 2, 3]
objKeys({a:1, b:2, c:3}); // ["a", "b", "c"]
And of course objReduce() to do almost anything imaginable...
Implementation details have been left as an excercise for the reader :-)
I like how the property is checked before creation, to avoid overwriting native properties.
if(!Array.prototype.indexOf) {
Array.prototype.indexOf = function(){ ... };
}

Categories

Resources