lodash _.partition method explained - javascript

I just discovered lodash.js and it's freaking GREAT man, however I stumbled onto an example which had me scratching my head.
let numbers = [4, 8, 15, 16, 23, 42];
let isEven = function(n) {
return n % 2 === 0;
};
let [evens, odds] = _.partition(numbers, isEven);
// evens: [4, 8, 16, 42]
// odds: [15, 23]
According to the documentation partition creates ONE array which contains two arrays containing results which returned true or false respectively, then how the outcome of the function TWO arrays?

Because the destructuring assignment allows you to assign the first element of the returned array to variable evens, and the second to odds. Since the returned array contains two arrays, both of the variables now refer to one-dimensional arrays.

Related

Using JS every() method

I am trying to test if an array is sorted in ascending order using the JS every method: checking if every element is smaller than the next index.
I don't understand why my code below is not working.
const testArray1 = [1, 2, 3, 4, 5, 6];
const testArray2 = [25, 51, 32, 12, 15];
const isAscending = (element, index, array) => {element < array[index + 1]};
console.log(testArray1.every(isAscending));// expecting true, but getting false
console.log(testArray2.every(isAscending));// expecting false, getting false
I am aware that the sort method exists, this is for a school exercice.
You have two problems.
Your arrow function always returns undefined because it is missing a return statement.
You are comparing the last value in the array to undefined (e.g. when i is 5 for the first array, element is 6 and array[5 + 1] is undefined) which is always false so you need to implement a special case for that entry.

Combining two arrays via the sum of two fields Javascript

Looking for general advice on approaches here. Description and pseudocode below:
Array1 has 100 objects type integer
Array2 has 100 objects type integer
Create Array 3 10,000 objects summing the two arrays
Array3.1 = Array1.[Field1] from 1 to 100 + Array2.1.[Field1]
Array3.2 = Array1.[Field1] from 1 to 100 + Array2.2.[Field1]
Array3.3 = Array1.[Field1] from 1 to 100 + Array2.3.[Field1]
……
Array3.100 = Array1.[Field1] from 1 to 100 + Array2.100.[Field1]
Challenges:
Not sure how to easily reference the field within an object in the array. I can pull up the object line but this returns the entire object whereas I only want to pull one field. This would be helpful beyond this particular question.
Not sure about the best method to create the new array, whether it should be a loop or something else.
Further background
The final objective will be to create an output that compares the sum of the specific field for every pair within the two arrays to find and then rank them from best to worst.
It's not that difficult.
Every entry in the resulting array is just the 2nd array with the value at the current index of the first array added to it.
const a1 = [0, 5, 10, 15, 20];
const a2 = [0, 2, 4, 6, 8];
const result = a1.map(x => a2.map(y => x + y));
console.log(result);
If you don't want the resulting array to nested, use flatMap:
const a1 = [0, 5, 10, 15, 20];
const a2 = [0, 2, 4, 6, 8];
const result = a1.flatMap(x => a2.map(y => x + y));
console.log(result);

Recursively make one level array from multi levels array in JavaScript

I'm confused a little, please help me anyone.
This is what I have
var arr = [
1,
2,
[11, 12, 13],
3,
[11, 12,
[21, 22]
]
];
As you can see, it's multi-lever array. Using recursion I need to make a one level array from it, which contains all elements from its children. Should be like this:
[1,2,11,12,13,3,11,12,21,22]
Here's how I'm doing it:
function getAllNumbers(arr) {
var allNumbers = [];
arr.forEach(function (el) {
if (Array.isArray(el)) {
allNumbers.concat(getAllNumbers(el))
} else {
allNumbers.push(el)
}
});
return allNumbers;
}
and it's not working. Gives me back only first level, like this: [1,2,3]
I'm particularly interested in recursion so please don't try to find other way.
please help
P.S. I can easily find sum of all elements with similar method just a little modified, but cannot do this :(
Almost everything was fine :)
just
The concat() method returns a new array comprised of the array on which it is called joined with the array(s) and/or value(s) provided as arguments.
so, instead of
allNumbers.concat(getAllNumbers(el))
should be
allNumbers = allNumbers.concat(getAllNumbers(el))
and it works :)

Javascript:: Find differences between array that contains duplicated values to a unique array of that array

I found many posts on stack overflow about that similar subject but none of them solve this issue here.
<script>
//Array GanginaA contains duplicated values.
//Array GanginaB contains only unique values that have been fetched from GanginaA
GanginaA=[0,1,2,3,4,5,5,6,7,8,9,9];
GanginaB=[0,1,2,3,4,5,6,7,8,9];
var hezi=<!--The Magic Goes Here-->
console.log(hezi);
/*
* Expected Output:
* 5,9
*/
</script>
GanginaA will always be longer or identical to GanginaB so there is no reason to calculate by the value of the longer array length.
GanginaB will always contains unique values that taken from GanginaA so it will always be the shorter array length or identical to GanginaA array.
Now it makes it a lot easier to find doubles.
You can use filter to get the elements like below
GanginaA = [0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9];
GanginaB = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
var hezi = GanginaB.filter(function (item, index) {
return GanginaA.indexOf(item) !== GanginaA.lastIndexOf(item)
});
console.log(hezi.join(" , ")); // 5, 9
the easier I can think of :
var hezi=[];
for (var i=0;i<GanginaA.length;i++){
hezi[GanginaA[i]] = GanginaA[i];
hezi[GanginaB[i]] = GanginaB[i];
}
hezi = hezi.filter (function(el){return el!=undefined;});
does everything in O(n) actions and not O(n^2)
Javascript's objects have hashmap like behaviour, so you can use them kind of like a set. If you iterate over all the values and set them to be keys within an object, you can use the Object.keys method to get an array of unique values out.
function uniqueValues() {
var unique = {};
[].forEach.call(arguments, function(array) {
array.forEach(function(value) {
unique[value] = true;
});
});
return Object.keys(unique);
};
This function will return the unique elements in any number of arrays, passed as arguments.
uniqueValues([1, 2, 3], [ 1, 1, 1], [2, 2, 2], [3, 3, 3]); // [ 1, 2 3 ]
One drawback to this method is that Javascript coerces all keys to strings, you can turn them back into numbers by changing the return statement to:
return Object.keys(unique).map(Number);

Underscore's similar functions: _.contains vs. _.some and _.map vs _.each

Is there a reason to use one over the other? It seems that _.some and _.map are easier to use or applicable to more situations (from my very limited experience) but from reading it, they sound as if they should do the same thing. I'm sure there are other instances of this and I'm all ears on learning some of the comparisons.
_.contains vs _.some
_.contains (_.contains(list, value, [fromIndex])
Returns true if the value is present in the list. Uses indexOf internally, if list is an Array. Use fromIndex to start your search at a given index.
_.some (_.some(list, [predicate], [context]))
Returns true if any of the values in the list pass the predicate truth test. Short-circuits and stops traversing the list if a true element is found.
The main difference between _.some and _.contains is that, contains checks if a given item is present in the given list and some checks if any of the elements in the list satisfies the predicate passed. So, they both are doing different tasks.
_.each vs _.map
_.each (_.each(list, iteratee, [context])
Iterates over a list of elements, yielding each in turn to an iteratee function.
_.map (_.map(list, iteratee, [context])
Produces a new array of values by mapping each value in list through a transformation function (iteratee).
_.map calls the function passed (iteratee) with each and every element of the list to create a new Array object, but _.each simply calls the function passed (iteratee) with each and every element (Note: this doesn't create an Array).
Basically _.each is the functional equivalent of for (var i = 0; i < array.length; i += 1) {...}. Again, they both are doing different jobs.
I think #thefourtheye's answer explains enough, but I thought that adding an example may help as well.
_.contains vs _.some
The big difference here is that _.contains allows you to provide a value and an index, while _.some allows you to provide a predicate.
So, for example, let's say we have an array with the first 10 numbers [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], how do we check if the array contains the number 5?
We can use the _.contains function:
_.contains([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 5); // True
We could use the _.some function as well, but it's a bit longer:
_.some([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], function(num) {
return num === 5;
}); // True
But, let's say we need to check if the array contains any even number? It's hard to do that with _.contains but with _.some you could do something like this:
_.some([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], function(num) {
return num % 2 === 0;
});
So yeah, there's a difference here, while _.contains is primarily used to check if an array contains a specific element, _.some could be used to check if an array contains an element with specific requirements.
_.each vs _.map
Both these loop through the entire array, but they both have a different meaning. With _.each it's quite simple, you can loop through an array:
_.each([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], function(num) {
console.log(num); // Will print each number
});
The _.map function on the other hand allows you to return something, it allows you to map an array to a new array. Let's say you want an array of every number, multiplied by 2, well, you can do that with _.map:
var newCollection = _.map([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], function(num) {
return num * 2;
});
console.log(newCollection); // Will contain the numbers 2, 4, 6, 8, ...
Yes, you could do that with an _.each loop as well by doing something like this:
var newCollection = [];
_.each([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], function(num) {
newCollection.push(num * 2);
});
console.log(newCollection);
But _.map is just a short and easier way of doing that.
1) _.contains vs _.some
I think, it is possible to say, that _.contains is special case of _.some.
That is,
_.contains( list, value )
is a shortcut for
_.some( list, function ( el ) { return value == 3; })
The second variant is just too verbose.
In lodash such useful shortcuts presents in many functions, for example:
var users = [
{ 'user': 'barney', 'age': 36, 'active': true },
{ 'user': 'fred', 'age': 40, 'active': false }
];
_.contains({ 'user': 'fred', 'age': 40 }, 'fred');
or
_.filter(users, { 'age': 36 });
2) _.map vs _.each
These functions are just different. _.map used for collection transformation. If your input has size of N, result of _.map also has size of N. In other words, _.map is expression - use it when you need to transform each element of input collection.
_.each is just a shortcut for the for loop. It is useful, because you don't need to calculate length of array as in
for (var i = 0, len = myArray.length; i < len; i++ ) {
}
When you use _.map or _.each properly, you declare explicitly your intentions.

Categories