JavaScript - Get Array Element Fulfilling a Condition

JavaScript - get array element fulfilling a condition

In most browsers (not IE <= 8) arrays have a filter method, which doesn't do quite what you want but does create you an array of elements of the original array that satisfy a certain condition:

function isGreaterThanFive(x) {
return x > 5;
}

[1, 10, 4, 6].filter(isGreaterThanFive); // Returns [10, 6]

Mozilla Developer Network has a lot of good JavaScript resources.

Typescript - get array that satisfy a condition

You must filter your array and verify that you have 2 in your roles :

const filteredUserMenus = userMenus.filter((userMenu) => {
return userMenu.roles.find((role) => role === '2');
});

short syntax :

const filteredUserMenus = userMenus.filter((userMenu) => 
userMenu.roles.find((role) => role === '2'));

EDIT : your data structure is bad, roles shouldn't be a string but an array of role. Anyway, if you can't change it, here is a solution :

const filteredUserMenus = userMenus.filter((userMenu) => {
return userMenu.roles.split(',').find((role) => role === '2');
});

short syntax :

const filteredUserMenus = userMenus.filter((userMenu) =>
userMenu.roles.split(',').find((role) => role === '2'));

How can I only keep items of an array that match a certain condition?

For this, you can use the Array#filter() method, introduced in ECMAScript5. It is supported in all browsers, except for IE8 and lower, and ancient versions of Firefox. If, for whatever reason, you need to support those browsers, you can use a polyfill for the method.

filter() takes a function as its first argument. For every item of the array, your function is passed three arguments - the value of the current item, its index in the array, and the array itself. If your function returns true (or a truthy value, e.g. 1, "pizza", or 42), that item will be included in the result. Otherwise, it won't. filter() returns a new array - your original array will be left unmodified. That means that you'll need to save the value somewhere, or it'll be lost.

Now, in the examples from the question:

var myNumbersArray = [1, 2, 3, 4, 5, 6, 7, 8];console.log(myNumbersArray.filter(function(num){  return !(num % 2); // keep numbers divisible by 2}));console.log(myNumbersArray); // see - it hasn't changed!
var myStringArray = ["This", "is", "an", "array", "with", "several", "strings", "making", "up", "a", "sentence."];console.log(myStringArray.filter(function(str){ return str.length < 3; // keep strings with length < 3}));console.log(myStringArray);
var myBoolArray = [true, false, 4, 0, "abc", "", "0"];console.log(myBoolArray.filter(Boolean));// wow, look at that trick!console.log(myBoolArray);

Get the indexes of javascript array elements that satisfy condition

You can use Array#reduce method.

var data = [{prop1:"abc",prop2:"qwe"},{prop1:"abc",prop2:"yutu"},{prop1:"xyz",prop2:"qwrq"}];
console.log( data.reduce(function(arr, e, i) { if (e.prop1 == 'abc') arr.push(i); return arr; }, []))
// with ES6 arrow syntaxconsole.log( data.reduce((arr, e, i) => ((e.prop1 == 'abc') && arr.push(i), arr), []))

How to optimise a condition which checks for each object of an array of objects whether specific properties are not undefined?

I understand the Q. in a way that the OP does not want to check for every object's value being not the undefined value, and the OP rather wants to check whether some predefined properties (e.g. by a key list) need to be present and also not equal to undefined.

In this case one could implement a function which checks via a list of property names (key list) for each passed item/object whether such an object fulfills the above mentioned requirement.

Such a function could be passed as callback function to every in order to detect whether any of an array's item/object does fulfill the requirement.

function isEveryPropertyFromBoundListDefined(item) {
const keyList = this; // the bound list of defined keys.

return keyList
.every(key => item[key] !== undefined);
}

const sampleData_1 = [{
a: 12, b: 14, c: undefined, d: undefined,
e: 56, f: "file 1", g: "file 2", h: undefined,
}];
const sampleData_2 = [{
e: 56, f: "file 1", g: "file 2", h: null,
}, {
h: 1, g: 2, f: 3, e: 4,
}];
const listOfToBeDefinedKeys = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'];

console.log(
sampleData_1
// make use of `every`'s 2nd `thisArg` parameter.
.every(isEveryPropertyFromBoundListDefined, listOfToBeDefinedKeys)
);
console.log(
sampleData_2
// make use of `every`'s 2nd `thisArg` parameter.
.every(isEveryPropertyFromBoundListDefined, ['e', 'f', 'g', 'h'])
);
.as-console-wrapper { min-height: 100%!important; top: 0; }

How to find first element of array matching a boolean condition in JavaScript?

Since ES6 there is the native find method for arrays; this stops enumerating the array once it finds the first match and returns the value.

const result = someArray.find(isNotNullNorUndefined);

Old answer:

I have to post an answer to stop these filter suggestions :-)

since there are so many functional-style array methods in ECMAScript, perhaps there's something out there already like this?

You can use the some Array method to iterate the array until a condition is met (and then stop). Unfortunately it will only return whether the condition was met once, not by which element (or at what index) it was met. So we have to amend it a little:

function find(arr, test, ctx) {
var result = null;
arr.some(function(el, i) {
return test.call(ctx, el, i, arr) ? ((result = el), true) : false;
});
return result;
}
var result = find(someArray, isNotNullNorUndefined);

Can you use the Array.prototype.find() to check against more than one condition to find something?

Your conditions are messed up. This

if (e !== 'Enter') {
return e
} else if (e !== '=') {
return e
}

will invariably result in one of those branches being fulfilled. If the first condition isn't fulfilled, then e is 'Enter', so e !== '=' is fulfilled.

You should also return a boolean (or a value that's known to be truthy or falsey) from a .filter callback - don't return the value being iterated over, because if the value is falsey, it won't be included in the resulting array.

const lastOperatorThatIsNotEqual = operatorArray.reverse().find(
e => e !== "=" && e !== 'Enter'
)

or

function test(e) {
if (e === 'Enter') {
return false;
}
if (e === '=') {
return false;
}
return true;
}

lastOperatorThatIsNotEqual = operatorArray.reverse().find(test)

How to get the number of elements for elements that satisfy a condition

So based on the edit the array with actual information we want is the value of the Items key.

myArr doesn't seem to be an array, but it's actually a key-value pair based on the edit as well.

Here is my attempt:

var myArr = JSON.parse(this.responseText);

//console.log(myArr.Items)
//Declare and initialize k-v pair.
var results = {};
for (var i = 0, len = myArr.Items.length; i < len; i++) {
var id_art = myArr.Items[i].id_a;
if (id_art == 123456) {
//console.log(i, myArr.Items[i]);
//Create the key-value pair and store the index information in the key.
results[i] = myArr.Items[i];
}
}

console.log(results);

Output:

{
'3': {
type: 'Image',
id_a: '123456',
value: 'moto_guzzi_v100_mandello.jpg',
number: 3,
id: 3
},
'4': {
type: 'Text',
id_a: '123456',
value: 'The star of the Piaggio group stand is without doubt ... Discover all his secrets with our video',
number: 2,
id: 2
}
}

Explanation: Since you have specified you do not care how the data is stored. I have put it in the key of a new key-value Object in Javascript (do they call these dictionaries or hashmaps here?).

Thus, you can access them now by cycling through the elements in the dictionary, or getting a list of just keys in the dictionary and choosing which value you would like to access.

For instance, to print out a list of keys that exist in this object, you might use:

for (let value of Object.keys(results)) {
console.log(value)
}

Let me know if I have understood you correctly.

Edit

To get the output mentioned in your comment, now using while:

var x = 0;
while (x < Object.entries(results).length) {
//console.log(Object.entries(results)[x][1]);
if (Object.entries(results)[x][1].type == "Image"){
console.log("The index is: ", Object.entries(results)[x][0]);
console.log("The value is: ", Object.entries(results)[x][1].value);
}
x++;

}

Output:
Sample Image

Property of first object in array being pushed but not second object

Notice that you are calling return within your for statement

Instead you should move it out:

const campgrounds = [
{ number: 1, view: 'ocean', partySize: 8, isReserved: false },
{ number: 5, view: 'ocean', partySize: 4, isReserved: false },
{ number: 12, view: 'ocean', partySize: 4, isReserved: true },
{ number: 18, view: 'forest', partySize: 4, isReserved: false },
{ number: 23, view: 'forest', partySize: 4, isReserved: true },
];

function findMyCampsites(campgrounds, view, partySize) {
const sites = [];
for (let i = 0; i < campgrounds.length; i++) {
if (
campgrounds[i].isReserved === false &&
campgrounds[i].view === view.toLowerCase() &&
campgrounds[i].partySize >= partySize
) {
sites.push(campgrounds[i].number);
}
}

if (!sites.length) {
return 'Sorry, no campsites with that view are available to host your party';
}

return sites;
}

const result = findMyCampsites(campgrounds, 'ocean', 4);

console.log(result);


Related Topics



Leave a reply



Submit