Check if a subset of numbers is at the beginning of the series or the bottom of the series using jQuery or javascript
For example: I installed 1,3,4,5,6,7,8,10,11
-
scenario 1: subset = 1,3,4 that is in the start of the series = Acceptable
-
scenario 2: subset = 8,10,11 that is in the end of the series = acceptable
-
scenario 3: subset = 1,3,10,11 that is in the beginning and end of the series = acceptable
-
scenario 4: subset = 1,3,6,8 that is in the beginning of the series and also in the middle of the series = Not acceptable .
The main thing to do is check if the given series is the start part or the end part, without breaking the series with jquery or javacript.
Help would be much appreciated
Thank you in advance
source to share
You can use a two-pass approach by first collecting a comparison with the same index from the beginning and the end (later denoted as left and right) for all subarav elements.
To indicate the result, 4 states are returned which mean
-
0
- no match, neither left nor right does not match the value, -
1
- the element on the left side of the array matches, -
2
- the element on the right side of the array matches, -
3
- coincidence of positions on both sides.
After collecting the values representing the match and position, the values should be combined with the desired result, true
or false
.
To test each value, you need a different value that represents the expected side. At the beginning, the expected side is set to 1
because it starts from the left side to check.
The temporary result of callback c Array#every
is a single check if the actual value is greater than or equal to the expected value. This turns on the indicator 3
because the value is on both sides. The zero value also exits the loop.
If a value is found 2
, it points to the right side, and all following items must be greater than 2
, so the expected value is set to 2
.
The solution presented can be shortened to simply return the required boolean.
function check(array, subarray) {
var expected = 1,
temp = subarray.map(function (a, i) {
var offset = array.length - subarray.length;
return (a === array[i]) + 2 * (a === array[i + offset]);
}),
result = temp.every(function (a) {
var r = a >= expected;
if (a === 2) {
expected = 2;
}
return r;
});
return temp.concat(result);
}
var array = [1, 3, 4, 5, 6, 7, 8, 10, 11];
console.log(check(array, [1, 3, 4])); // true
console.log(check(array, [8, 10, 11])); // true
console.log(check(array, [1, 3, 10, 11])); // true
console.log(check(array, [1, 3, 6, 8])); // false
console.log(check([1, 2, 3, 4, 5, 6], [1, 4, 3, 6])); // false
console.log(check([1, 2, 3, 4, 5, 6], [1, 4, 3, 6])); // false
console.log(check([1, 2, 3, 2, 3, 4], [3, 2, 3, 2])); // false
console.log(check([1, 2, 3, 2, 3, 4], [1, 2, 3, 4])); // true
.as-console-wrapper { max-height: 100% !important; top: 0; }
Short version without temp array.
function check(array, subarray) {
var offset = array.length - subarray.length,
expected = 1;
return subarray.every(function (a, i) {
var state = (a === array[i]) + 2 * (a === array[i + offset]),
result = state >= expected;
if (state === 2) {
expected = 2;
}
return result;
});
}
var array = [1, 3, 4, 5, 6, 7, 8, 10, 11];
console.log(check(array, [1, 3, 4])); // true
console.log(check(array, [8, 10, 11])); // true
console.log(check(array, [1, 3, 10, 11])); // true
console.log(check(array, [1, 3, 6, 8])); // false
console.log(check([1, 2, 3, 4, 5, 6], [1, 4, 3, 6])); // false
console.log(check([1, 2, 3, 4, 5, 6], [1, 4, 3, 6])); // false
console.log(check([1, 2, 3, 2, 3, 4], [3, 2, 3, 2])); // false
console.log(check([1, 2, 3, 2, 3, 4], [1, 2, 3, 4])); // true
.as-console-wrapper { max-height: 100% !important; top: 0; }
source to share
One simple approach: remove the matching numbers from the beginning and end of both arrays and see if there are leftovers.
var checkIt = function(arr,subarr) {
// strip off matching numbers at the beginning
while (subarr.length && arr[0] === subarr[0]) {
arr.shift();
subarr.shift();
}
// strip off matching numbers at the end
while (subarr.length && arr[arr.length - 1] === subarr[subarr.length - 1]) {
arr.pop();
subarr.pop();
}
// if there aren't any leftovers, return true
return (subarr.length === 0)
}
console.log(checkIt( [1, 3, 4, 5, 6, 7, 8, 10, 11],[1, 3, 4]));
console.log(checkIt( [1, 3, 4, 5, 6, 7, 8, 10, 11],[8, 10, 11]));
console.log(checkIt( [1, 3, 4, 5, 6, 7, 8, 10, 11],[1, 3, 10, 11]));
console.log(checkIt( [1, 3, 4, 5, 6, 7, 8, 10, 11],[1, 3, 6, 8]));
// pathological edge case:
console.log(checkIt( [1,2,3,2,1],[1,2,3,2,1] ))
// This returns true, but based on the rules of the puzzle I'm honestly not sure whether that correct.
source to share
You will go through the subars from left to right and from right to left and stop where the value does not match the value in the main array at the "corresponding position", that is, counting the position from the same side of the array.
If at the end of both cycles all values of the submatrix coincide, i.e. the two indices intersect with each other, then the result true
.
Here is the code:
function isSubsetAtEnds(array, subarray) {
const diff = array.length - subarray.length;
let i, j;
if (diff < 0) return false;
for (i = 0; i < subarray.length; i++)
if (array[i] !== subarray[i]) break;
for (j = subarray.length - 1; j >= i; j--)
if (array[j+diff] !== subarray[j]) break;
return j < i;
}
var array = [1, 3, 4, 5, 6, 7, 8, 10, 11];
console.log(isSubsetAtEnds(array, [1, 3, 4])); // true
console.log(isSubsetAtEnds(array, [8, 10, 11])); // true
console.log(isSubsetAtEnds(array, [1, 3, 10, 11])); // true
console.log(isSubsetAtEnds(array, [1, 3, 6, 8])); // false
source to share