Can Somebody Explain this Function? - javascript

function doesOwnSet(player, type) {
// we'll use "chaining" here, so every next method will be called upon
// what previous method have returned
// `return` statement will return the result of the very last method
// first, lets take an array of `position` object keys
// which are "position1", "position2" and so on
return Object.keys(positions)
// then, create an array of positions object
// this will return Array
.map(function (key) {
return positions[key];
})
// then, pick up only positions with specified type (aka set)
// this will return Array
.filter(function (pos) {
return pos.type === type;
})
// finally, check if specified player owns every position of the set
// this will return Boolean
.every(function (pos) {
return pos.owner === player;
});
}
I don't understand where the words "key" and "pos" come from. Are these the names of the functions? I really don't get it despite the comments. It was an answer to this question. The code works, but I just don't understand what it does.

Object.keys returns an Array of the "own" keys of the object.
The .map(), .filter() and .every() iterate the array, passing each value to the callback one at a time, so the key in .map() is the object key for the current iteration.
Whatever .map() callback returns gets added as a member of a new Array, which is returned, so .filter() and .every() operate on the new Array values.
The .filter() will create an Array of the values where the callback returned true (or any truthy value).
The .every() will return true if its callback returns a truthy value for every iteration, otherwise it returns false.
Put calls to console.log() inside the callbacks to see what the values hold.
function doesOwnSet(player, type) {
// we'll use "chaining" here, so every next method will be called upon
// what previous method have returned
// `return` statement will return the result of the very last method
// first, lets take an array of `position` object keys
// which are "position1", "position2" and so on
return Object.keys(positions)
// then, create an array of positions object
// this will return Array
.map(function (key) {
console.log(key);
return positions[key];
})
// then, pick up only positions with specified type (aka set)
// this will return Array
.filter(function (pos) {
console.log(pos);
return pos.type === type;
})
// finally, check if specified player owns every position of the set
// this will return Boolean
.every(function (pos) {
console.log(pos);
return pos.owner === player;
});
}

Related

array.every() works on only first element

I have an array
errorPriority: string[] = ['shippingError', 'paymentInfoError', 'generalError'];
I need a function call to be looped on every element of array, but somehow after executing function for first element 'shippingError', the loop stops. Below is the function call
this.errorPriority.every(this.getErrorData);
And the function that is executed
getErrorData = (value: string): void => {
if (eval(this.objectPath[value as keyof ObjectPath]) && eval(this.objectPath[value as keyof ObjectPath]).length)
this.checkoutState.errors[value] = eval(this.objectPath[value as keyof ObjectPath]);
}
It sometimes, works on array element, but mostly stops after first element, Am I missing something, please help
I expect function should be looped on every array element
The every() method tests whether all elements in the array pass the test implemented by the provided function. It returns a Boolean value.
Source
this means Array#every() checks if every item in array meets the criteria tested by given function, and that means the given function should return a boolean value. Since your function does return void or in javascript undefined, this will be interpreted as false. And because every returns true only if all elements return a truthy value, the iteration can be aborted after the first falsy value.
to run your code on every item you need to use forEach
You are using every function, it will just test if ALL elements of your array successfully pass your function.
So the given function MUST return a boolean (true or false) but you are returning void. try to return "true" if your condition is successfull
getErrorData = (value) => {
if (eval(this.objectPath[value]) && eval(this.objectPath[value]).length) {
this.checkoutState.errors[value] = eval(this.objectPath[value]);
return true;
}
}
from the MDN documentation the definition of array.every() is
every() method tests whether all elements in the array pass the test
implemented by the provided function. It returns a Boolean value.
so array.every returns a boolean. in your code you don't return anything. if the condition is true, you only assign a new property.
the following should work:
getErrorData = (value) => {
if (eval(this.objectPath[value]) && eval(this.objectPath[value]).length) {
this.checkoutState.errors[value] = eval(this.objectPath[value]);
return true;
}
return false
}

How does find method works with the array?

Suppose I have an array and I want to find first number in an array which is greater than 25. It checks for the condition i.e. whether the number is greater than 25 and should return true when the condition satisfies but it returns the value.Help me debug how it is working.
const numbers=[10,20,30,40,50]
function findNumJS(numbers,num){
const output=numbers.find(function(n){
return n>num
})
return output
}
console.log(findNumJS(numbers,25))
The find() method returns the value of the first element in an array that pass a test (provided as a function).
The find() method executes the function once for each element present in the array:
If it finds an array element where the function returns a true value, find() returns the value of that array element (and does not check the remaining values)
Otherwise it returns undefined
Note: find() does not execute the function for empty arrays.
Note: find() does not change the original array.
For more : https://www.w3schools.com/jsref/jsref_find.asp
Array​.prototype​.find()
The find() method returns the value of the first element in the array that satisfies the provided testing function. Otherwise undefined is returned.
If you want to return Boolean value then you can use Array​.prototype​.some()
const numbers=[10,20,30,40,50]
function findNumJS(numbers,num){
const output=numbers.some(function(n){
return n>num
})
return output
}
console.log(findNumJS(numbers,25))
Actually find method go through each and every array item one by one and check the provided condition. If the provided condition is satisfied then the find method returns the matched item immediately.
const numbers=[10,20,30,40,50]
numbers.find(number => number > 25)
//In first iteration number -> 10 ; which is not greater than 25
//In second iteration number -> 20 ; which is not greater than 25
//In third iteration number -> 30 ; which is greater than 25, so the condition satisfied and it returns the value
if you find the first element in the arrays you can use .find
but you want to check is there any element that satisfy your condition. so you should use .some.
for your example you can change it like this:
const numbers=[10,20,30,40,50]
function findNumJS(numbers,num){
const output=numbers.some(function(n){
return n>num
})
return output
}
console.log(findNumJS(numbers,25))
you can decrease your code like this or just user .some:
const numbers=[10,20,30,40,50]
function findNumJS(numbers,num){
return numbers.some(function(n){
return n>num
})
}
console.log(findNumJS(numbers,25))
for more information see this:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some
function isBigEnough(value) {
return function(element, index, array) {
return (element >= value);
}
}
var filtered = numbers = [10, 20, 30, 40, 50].filter(isBigEnough(25));
console.log(filtered)
The javascript Array.find(callback) the function returns the first item of the array, where the function returns true.

Why does my function require two return statements for it to be correct?

So my coding exercise has me create a function “getElementsGreaterThan10AtProperty” that returns an array containing the elements within the array, located at the given key, that are greater than 10. Playing around with the code I cant figure out why my filter method requires two return statements. Any tips to help me understand would be very appreciated.
function getElementsGreaterThan10AtProperty(obj, key) {
if (!Array.isArray(obj[key]) || obj[key].length < 1 ) {
return [];
} else {
return obj[key].filter(function(item){
return item > 10;
});
}
}
Also,
If the array is empty, it should return an empty array.
If the array contains no elements greater than 10, it should return an empty array.
If the property at the given key is not an array, it should return an empty array.
If there is no property at the key, it should return an empty array
The Array.prototype.filter function returns a new Array using a filter function.
The callback filter function must return a Boolean indicating whether or not an item is kept. So...
// the outer `return` returns the resulting Array.
return obj[key].filter(function(item){
// The inner `return` returns a pass/fail (true/false)
return item > 10;
});

Dynamically compare two arrays

I'm trying to compare two arrays, one being called values and other one called feeds.
The feeds array has multiple set of values, how can I check which feed contains the correct set of values to match?
Fiddle link: https://jsfiddle.net/v7ussmbb/1/
I understand the async nature, ie console.log rules before the loop completes which is fine, I just need the comparison part.
I would iterate all your feeds until one matches all the rules, to achieve that I would do something like this: https://jsfiddle.net/canastro/v7ussmbb/4/
// Hold the active feed
var active_feed = '';
// Iterate until one item matches all rules
const found = feeds.some(function(item) {
//console.log('item: ', item);
// Check if all rules match
const match = item.rules.some(function(rule) {
// Get rule to apply by comparing values keys with the rule id
let ruleToApply;
Object.keys(values).some(function(key) {
const isRule = key === String(rule.id);
if (isRule) { ruleToApply = values[key]; }
return isRule;
});
return ruleToApply === rule.value;
});
if (match) { active_feed = item; }
return match;
});
console.log('active_feed: ', active_feed);
To achieve this I used some function:
some() executes the callback function once for each element present in
the array until it finds one where callback returns a truthy value (a
value that becomes true when converted to a Boolean). If such an
element is found, some() immediately returns true. Otherwise, some()
returns false. callback is invoked only for indexes of the array which
have assigned values; it is not invoked for indexes which have been
deleted or which have never been assigned values.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some

How to check if an object is "deep empty"?

i have a method that returns an object that contains 4 objects:
function getFiles() {
var documents = {};
documents.files1ToBeCompleted = DocumentsService.getFiles1Uncompleted();
documents.files2ToBeCompleted = DocumentsService.getFiles2Uncompleted();
documents.files3ToBeCompleted = DocumentsService.getFiles3Uncompleted();
documents.files4ToBeCompleted = DocumentsService.getFiles4Uncompleted();
return documents;
}
I'm trying to use Underscore function ._isEmpty to verify if the object is empty, i mean the case in which i get an object with empty sub-objects.
But even all its 4 objects are empty, it is not empty because it contains 4 items.
Do you know any way to check if an object is "deep empty"?
Here's what worked for me. It is recursive and takes care of all nested objects (uses lodash).
function isEmptyDeep(obj) {
if(isObject(obj)) {
if(Object.keys(obj).length === 0) return true
return every(map(obj, v => isEmptyDeep(v)))
} else if(isString(obj)) {
return !obj.length
}
return false
}
It first checks if there are no keys, and returns true in that case.
Then it checks the keys and runs isEmptyDeep on each. If the value is an object (or array), it will continue recursion.
If there's an empty array or empty string, length will be 0 and will be considered empty.
If the value is 0, false, or other falsy values, then it would be considered not empty. If you want to consider falsey values as empty, this as the first line in the function above:
if(!obj) return true
Thanks to Bergi that lead me to this working solution:
_.every(documentsObject, function(property) { return _.isEmpty(property); });
that returns true if the object is "deep empty", false otherwise.

Categories

Resources