find value exist in a array of array in javascript - javascript

I have an array of array, how to find if a value exists inside this array in javascript. Here is the code example
let multival = [['Individual'], ['Non-Individual'],null]
Now I have to find if string 'Non-Individual' is present in this array of array or not, can anyone have solution in this regards

You could use Array.prototype.some() to check the string is present in the array of array.
const multival = [['Individual'], ['Non-Individual'], null];
const searchItem = 'Non-Individual';
const ret = multival.some(
(x) => Array.isArray(x) && x.some((y) => y === searchItem)
);
console.log(ret);

Out of interest, a recursive solution for arrays with any level of nested depth (And I believe quicker than a solution using flat() due to short circuiting):
function nestedIncludes(arr, val) {
let check = i => Array.isArray(i) ? i.some(check) : i === val;
return arr.some(check);
}
let myArr = [[[['foo'],1],2],3,5];
let test = nestedIncludes(myArr, 'foo');
console.log(test); // true

Try flat and includes function:
const multival = [['Individual'], ['Non-Individual'],null]
const exists = multival.flat().includes('Non-Individual');
console.log(exists ? 'exists' : 'non-exists')
Note: I didn't notice, but User863 comment with the same answer.

Method 1, Using findIndex, optional chaining and includes
Method 2, Using some, optional chaining and includes
// Method 1, Using `findIndex` and `includes`
const find = (arr, item) => arr.findIndex((arr2) => arr2?.includes(item)) > -1;
// Method 2, Using `some` and `includes`
const find2 = (arr, item) => arr.some((arr2) => arr2?.includes(item));
let multival = [["Individual"], ["Non-Individual"], null];
console.log(find(multival, "Individual"));
console.log(find2(multival, "Individual"));
console.log(find(multival, ""));
console.log(find2(multival, ""));

Related

In javascript, filter and map an array in one function?

In Javascript, Array.filter() takes an array and filters it down based on a certain criteria.
const a = [1,2,3,4,5].filter(el => el > 3);
console.log(a);
Result: [4,5]
Array.map() takes an array and returns a new array of equal length, usually mutating the original's elements in the process.
const a = [1,2,3,4].map(el => el + 10);
console.log(a);
Result: [11,12,13,14,15]
My question is, besides combining the two functions like this:
let a = [1,2,3,4,5].filter(el => el > 3).map(el => el + 10);
console.log(a);
is there an efficient way to filter and mutating an array, that doesn't involve multiple lines of code like most Array.forEach, for, and for..in routines? I know that Array.filter().map() is pretty efficient, I'm just wondering if it can be further streamlined.
Use Array.prototype.reduce to take care of filtering and mapping all at once.
let a = [1,2,3,4,5].reduce((arr, el) => el > 3 ? arr.concat(el + 10) : arr, []);
console.log(a);
You could also make your own mapIf polyfill function.
// Reduce Only
if (Array.prototype.mapIf === undefined) {
Array.prototype.mapIf = function(predicateFn, applyFn) {
return this.reduce((ref, el) => predicateFn(el) ? ref.concat(applyFn(el)) : ref, []);
};
}
// Filter + Map
if (Array.prototype.mapIf === undefined) {
Array.prototype.mapIf = function(predicateFn, applyFn) {
return this.filter(predicateFn).map(applyFn);
};
}
let a = [1,2,3,4,5].mapIf(el => el > 3, el => el + 10);
console.log(a);

How do I get multiple index on an Array

I am trying to get multiple index positions on an Array for a Boolean value.
I have tried applying a loop using while and for to iterate more then one index position with no success so far.
Here is my code:
let jo = [1,2,3,4,5]
let ji = [1,2,3]
let checker = (arr1,arr2) => {
let falsy = arr1.every(num => arr2.includes(num)) == false ?
arr1.map(falsy => arr2.includes(falsy)) : "tba";
//the block below is the frustrated attempt:
let i = falsy.indexOf(false);
while(i>=0){
return falsy.findIndex(ih => ih == false)
}
}
console.log(checker(jo,ji))
I would like to get the index where false occurs stored in a variable that has iterated over all array so I can use this variable to return just the false values on falsy like this:
return falsy[i] = [4,5]
Then after that I will add more to the first if statement to check both arr1 x arr2 or arr2 x arr1
Thanks in advance!
It looks like you're attempting to get the difference between two arrays. This is a fairly comment use-case for Sets. In this case, your code would look like this:
let jo = [1,2,3,4,5]
let ji = [1,2,3]
const checker = (arr1, arr2) => {
return new Set(arr1.filter(x => !new Set(arr2).has(x)))
}
console.log(checker(jo, ji)); // {4, 5}
If you wanted to get the indexes of the differences, you would need to apply a map to the result of the new Set like so:
const checker = (arr1, arr2) => {
const difference = new Set(arr1.filter(x => !new Set(arr2).has(x)));
return Array.from(difference).map(value => arr1.indexOf(v));
}

Javascript Array.some() and Array.every() equivalent for Set?

In JavaScript, is there an equivalent of Array.some() and Array.every() for the Set built-in object?
No, the only built-in methods on Set.prototype are:
Set.prototype​.add()
Set.prototype​.clear()
Set.prototype​.delete()
Set.prototype​.entries()
Set.prototype​.for​Each()
Set.prototype​.has()
Set.prototype​.values()
Set.prototype​[##iterator]()
It'd probably be easiest to just convert the set to an array, and then use the array methods.
const set1 = new Set([1, 2]);
const set2 = new Set([-1, 2]);
const allPositive = set => [...set].every(num => num > 0);
console.log(
allPositive(set1),
allPositive(set2)
);
It's not natively available on the Set prototype, but if you found yourself needing this frequently, you could easily extent Set to add it.
class extendedSet extends Set{
every(f){
return Array.prototype.every.call([...this], f)
}
some(f){
return Array.prototype.some.call([...this], f)
}
}
let a_set = new extendedSet([1, 2, 3, 4]);
console.log(a_set.every(n => n < 2))
console.log(a_set.some(n => n < 2))
// still works as a Set
console.log(a_set.has(4))
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set#Methods is the documentation for the list avaiable methods for the Set
Methods:
Set.prototype​.add()
Set.prototype​.clear()
Set.prototype​.delete()
Set.prototype​.entries()
Set.prototype​.for​Each()
Set.prototype​.has()
Set.prototype​.values()
Set.prototype​##iterator
In your context you could do something like below:
Array.from(set).some() or Array.from(set).every()
For more info regarding Array vs Set
Other answers suggest first converting the set to an array and then using some array method. This is completely unnecessary and even sub-optimal.
You can use a for loop on the set instance itself, iterate over it, find an element that matches a given condition, then break the loop:
function some(set, predicate) {
for (const item of set)
if (predicate(item))
return true;
return false;
}
function every(set, predicate) {
for (const item of set)
if (!predicate(item))
return false;
return true;
}
const set = new Set([ 42, 17, -1, 8.3 ]);
every(set, (item) => typeof item === "number"); // true
every(set, (item) => item > 0); // false
some(set, (item) => item < 0); // true
some(set, (item) => item === 0); // false

Map and filter an array JavaScript

I’m trying to map a nested array and return the words that have more letters than 6, I have been stuck for a while with this problem so I’d like to get some help
const array = [["hellow",'pastas'],["travel", "militarie"],["oranges","mint"]]
const arrayOne = array.map(new => new).filter(arr =>arr.length > 6)
You can flat array first and than filter out words with length greater than 6
const array = [['hellow','pastas'],['travel', 'militaries'],['oranges','mint']]
const arrayOne = array.flat(1).filter(e=> e.length > 6 )
console.log(arrayOne)
You can use the code below. This code uses .map() and .filter() to check if the length is greater than 6, and adds it to the array if it is.
const array = [["hellow","pastas"],["travel", "militarie"],["oranges","mint"]];
const arrayOne = array.map(e1 => e1.filter(e2 => e2.length > 6)).flat();
console.log(arrayOne);
I think better will be the filter() method instead.
array.filter(function (c) {
return c.length < 6;
});
But first use the flat() method.
There are many ways to do it.
You can use flatMap and filter:
const array = [['hellow','pastas'],['travel', 'militarie'],['oranges','mint']];
const result = array.flatMap(x => x.filter(y => y.length > 6));
console.log(result);
Another way is to use reduce and filter:
const array = [['hellow','pastas'],['travel', 'militarie'],['oranges','mint']];
const result = array.reduce((acc, x) => [...acc, ...x.filter(y => y.length > 6)], []);
console.log(result);

What is the javascript equivalent of numpy argsort?

I want to sort the imgUrl array by click count. I have two arrays.
clickCount = [5,2,4,3,1]
imgUrl = ['1.jpg','2.jpg','3.jpg','4.jpg','5.jpg']
In numpy it is easy. I use order = np.argsort(clickCount) then I create another array newArray = [imgUrl[i] for i in order].
How do I achieve the same effect in javascript (preferably vanilla)?
You can use a Schwartzian transform also known as Decorate-Sort-Undecorate (DSU) in python.
DSU:
Decorate - Use Array#Map to enrich each item in the array with the needed sort data
Sort - sort using the added data
Undecorate - extract the sorted data using Array#map again
Demo:
const dsu = (arr1, arr2) => arr1
.map((item, index) => [arr2[index], item]) // add the args to sort by
.sort(([arg1], [arg2]) => arg2 - arg1) // sort by the args
.map(([, item]) => item); // extract the sorted items
const clickCount = [5,2,4,3,1];
const imgUrl = ['1.jpg','2.jpg','3.jpg','4.jpg','5.jpg'];
const result = dsu(imgUrl, clickCount);
console.log(result);
thanks to dankal444 for the refactor to the function
For completeness, here's my solution to the actual answer (providing argsort function), by expanding on Ori's answer with DSU.
Since sort is by default taking the first element, so implementing it as DSU is merely adding an index, sorting it, then taking the indices.
let decor = (v, i) => [v, i]; // set index to value
let undecor = a => a[1]; // leave only index
let argsort = arr => arr.map(decor).sort().map(undecor);
clickCount = [5, 2, 4, 3, 1]
imgUrl = ['1.jpg', '2.jpg', '3.jpg', '4.jpg', '5.jpg']
order = argsort(clickCount);
newArray = order.map(i => imgUrl[i])
console.log(newArray);
Functional approach (like #Ori Drori's code) is always a charm to watch, but in this case, you only need to re-arrange an array's items. I believe that there is a simpler way to go and is a much easier code to read.
const clickCount = [5,2,4,3,1];
const imgUrl = ['1.jpg','2.jpg','3.jpg','4.jpg','5.jpg'];
sortByArrayRefOrder = (data, orderRefArr) => {
let orderedArr = [], i=0;
orderRefArr.map( o => { orderedArr[o-1] = data[i++]});
return orderedArr.reverse();
}
console.log ( sortByArrayRefOrder(imgUrl, clickCount) );

Categories

Resources