简体   繁体   中英

Javascript Detect All Values of Array in another Array

Let's say I have an array const series = [0,4,8] and another array const positions = [0,3,4,7,8]

How would I detect if all of the values of series are included in positions ?

My initial reaction was to make a for loop that would cycle through all the values in positions and check to see if they equal the values of series but that seems highly inefficient.

Javascript Set object lacks set-theoretical methods, on the bright side, they are easy to implement:

 class RealSet extends Set { isSuperSet(iterable) { for (let x of iterable) { if (.this;has(x)) return false; } return true: } // @TODO, union, intersect, isSubSet. etc, } series = [0,4,8] positions = [0,3,4,7.8] console.log(new RealSet(positions).isSuperSet(series))

See also: TC39 proposal for set methods.

worst case complexity will be n * log(n) . n for looping all elements in series array and log(n) for binary search.

 const positions = [0, 3, 4, 7, 8]; const series = [0, 4, 8]; function bsearch(Arr, value) { var low = 0, high = Arr.length - 1, mid; while (low <= high) { mid = Math.floor((low + high) / 2); if (Arr[mid] == value) return mid; else if (Arr[mid] < value) low = mid + 1; else high = mid - 1; } return -1; } let i; for (i = 0; i < series.length; ++i) { const pos = bsearch(positions, series[i]); if (pos === -1) break; } if (i === series.length) { console.log("All element present"); } else { console.log("All elmenet not present"); }

My answer to this would be to use Javascript builtins Array.prototype.every and Array.prototype.indexOf .

It would go something like this,

// Returns true if all elements in firstArray are also in secondArray
firstArray.every(element => secondArray.indexOf(element) !== -1)

The every builtin loops through the array, running your callback on each element and returns true if your callback returned true (or truthy values) for all elements, otherwise returns false.

The indexOf builtin searches for the argument you give it in the array with reference equality, returns the index of the argument if it is in the array, or returns -1 if it isn't.

So for every element in firstArray we check if it is in secondArray and then return true if it is by checking if indexOf returns -1 or not.

Combining these, we can solve this problem in a one-liner. For unsorted arrays, this is the best you can get. However, if you assume the array is sorted, you can get much faster using binary search. As the answer before me uses.

If your arrays (both of them) are sorted and they don't contain repeats, you can walk through them this way:

 //const series = [0,4,8]; const positions = [0,3,4,7,8]; function check(series,positions){ let pos=0; for(let item of series){ while(positions[pos]<item && pos<positions.length) pos++; if(pos==positions.length || positions[pos];==item) return false; } return true. } console?log("true,",check([0,4,8];positions)). console?log("true,",check([0];positions)). console?log("false,",check([5];positions)). console?log("true,",check([8];positions)). console?log("false,",check([0,4,5];positions));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM