I am going through a lesson on Javascript Arrays where we have to understand certain what is under the hood of underscoreJS methods. I need to write a function for the _.each method which will allow me to iterate over a single array and return a modified nested array that includes the index for each value.
For example:
var myArray = ['a', 'b', 'c'];
after the method each is called on myArray the new array should look like:
myArray = [ [ 'a', 0 ], [ 'b', 1 ], [ 'c', 2 ] ];
I have been searching on google for a day and have not found anything specific to this task. Stuck and need some help! Thank you.
_.each iterates over your array and has the following signature
function(value, index, array)
So lets see how it could be done ...
var result = [];
_.each(myArray, function(value, index, array){
result.push([value, index]); // <= does the work
}
This is not the ideal way (you should use map) but does illustrate how the each works.
Good luck
You can do it like below by using Array.prototype.reduce() function,
var myArray = ['a', 'b', 'c'];
var result = myArray.reduce(function(a,b,i){
return (a.push([b,i]), a)
},[]);
console.log(result); // [['a',0],['b',1],['c',2]];
Or as #bergi said you can do it with Array.prototype.map() also,
var myArray = ['a', 'b', 'c'];
var result = myArray.map(function(itm,i){
return [itm,i];
});
console.log(result); // [['a',0],['b',1],['c',2]];
Just use Array#map():
The map() method creates a new array with the results of calling a provided function on every element in this array.
var myArray = ['a', 'b', 'c'],
result = myArray.map(function (a, i) {
return [a, i];
});
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
If you're learning _.each method, you can do it like this
var myArray = ['a', 'b', 'c'];
_.each(myArray, function (e, i) {
myArray[i] = [e, i];
});
document.write(JSON.stringify(myArray));
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
But for your case better to use _.map function
Related
I want to get the remainder of an iterable like an array. Like so:
var arr = ['a', 'b', 'c'];
var brr = arr.slice(1);
But is there a terser way (maybe using destructuring assignment?).
Yes there is:
var [,...brr] = arr; // ['b', 'c']
Multiple elision also works:
var [,,...brr] = arr; // ['c']
I'm basically using $all operator in mongo and the input i get might be array or single element as following. So how do use underscore to put all the elements in one array and then
userId = 'a';
userIds = ['a', 'b', 'c'];
otherId = ['a'] or 'a';
searchArray = [userId, userIds, otherId]
db.collections.find({userIds: {$all: searchArray}})
You can use union as long as they are arrays.
_.union(arrays)
var userId = ['a'],
userIds = ['a', 'b', 'c'];
otherId = ['a'],
searchArray = _.union(userId, userIds, otherId);
If all variables aren't promised to be arrays, you probably want the flatten method.
userId = 'a'; // strings
userIds = ['a', 'b', ['c']]; // multidimensional array
otherId = ['a']; // single dimensional array
searchArray = _.flatten([userId, userIds, otherId]);
db.collections.find({userIds: {$all: searchArray}})
No need for underscore, you can use concat:
var userId = ['a'],
userIds = ['a', 'b', 'c'],
otherId = ['a'];
var arr = userId.concat(userIds, otherId)
This will work even if one of those is not an array but just a number or string. Working example here:
http://codepen.io/anon/pen/qbNQLw
What is the fastest algorithm for getting from something like this:
var array = [ [1,'a'], [2,'b'], [3,'c'] ];
to something like this:
Object { 1: "a", 2: "b", 3: "c" }
so far this is what i've come up with:
function objectify(array) {
var object = {};
array.forEach(function(element) {
object[element[0]] = element[1];
});
return object;
}
which works fine, but it seems kind of clumsy. Is there a better way? Would something like reduce() work and would that be any faster?
With Object.fromEntries, you can convert from Array to Object:
var array = [
[1, 'a'],
[2, 'b'],
[3, 'c']
];
var object = Object.fromEntries(array);
console.log(object);
You could indeed use Array.prototype.reduce:
function objectify(array) {
return array.reduce(function(p, c) {
p[c[0]] = c[1];
return p;
}, {});
}
where p is the result of the previous iteration, initially {}, and c is the current element of the array.
It's unlikely to be any faster than array.forEach, but it is IMHO cleaner. I don't believe there's any simpler implementation than this.
NB: a function to do exactly this already exists in the Underscore library: _.object(array)
Terse version using modern syntax:
let objectify = a => a.reduce( (o,[k,v]) => (o[k]=v,o), {} );
I use this technique as part of a terse query string parser:
// Converts "?foo=bar&j=1&go" into { foo:'bar', j:'1', go:true }
function parseQueryString(qs) {
var q = decodeURIComponent;
return qs.replace(/^\?/,'').split('&').map(s => s.split('='))
.reduce((o,[k,v]) => (o[q(k)] = v?q(v):true, o), {});
}
Lodash has a _.fromPairs method that does exactly that.
From the documentation:
_.fromPairs([['a', 1], ['b', 2]]);
// => { 'a': 1, 'b': 2 }
You can wrap the entire thing within Array.prototype.reduce, like this
function objectify(array) {
return array.reduce(function(result, currentArray) {
result[currentArray[0]] = currentArray[1];
return result;
}, {});
}
console.log(objectify([ [1, 'a'], [2, 'b'], [3, 'c'] ]));
# { '1': 'a', '2': 'b', '3': 'c' }
We are just accumulating the key-value pairs in the result object and finally the result of reduce will be the result object and we are returning it as the actual result.
I'm a newbie with Underscore.js.
Recently I read the documentation about reduce and reduceRight but I couldn't understand what is the difference between the two.
I will appreciate any help and example.
Well, _.reduce iterates over the collection starting at the first index and finishing on the last index while _.reduceRight does the same thing but starts at the last index and finishes on the first index.
var list = ['a', 'b', 'c'];
_.reduce(list, function(memo, item) { memo.push(item); return memo; }, []);
=> ['a', 'b', 'c']
_.reduceRight(list, function(memo, item) { memo.push(item); return memo; }, []);
=> ['c', 'b', 'a']
Assuming we have:
array1 = ['A', 'B', 'C', 'D', 'E']; array2 = ['C', 'E'];
Is there a proven and fast solution to compare two arrays against each other, returning one array without the values appearing in both arrays (C and E here).
So:
array3 = ['A', 'B', 'D']
should be the output of the solution. (jquery may be involved)
thx.
I accepted Matthews Solution, but dont want to ignore a different faster solution i just found.
var list1 = [1, 2, 3, 4, 5, 6];
var list2 = ['a', 'b', 'c', 3, 'd', 'e'];
var lookup = {};
for (var j in list2) {
lookup[list2[j]] = list2[j];
}
for (var i in list1) {
if (typeof lookup[list1[i]] != 'undefined') {
alert('found ' + list1[i] + ' in both lists');
break;
}
}
Source: Optimize Loops to Compare Two Arrays
This is a set difference. A simple implementation is:
jQuery.grep(array1, function(el)
{
return jQuery.inArray(el, array2) == -1;
});
This is O(m * n), where those are the sizes of the arrays. You can do it in O(m + n), but you need to use some kind of hash set. You can use a JavaScript object as a simple hash set for strings. For relatively small arrays, the above should be fine.
a proven fast solution that i know of is a binary search that you can use after you sort one of the arrays. so the solution takes time that depends on the sorting algorithm. but is at least log(N).