Related
I tried to write a function that would find in a multidimensional array (with values from 3 to 7) repeating values for at least 3 times next to each other (vertical and horizontal). And if it finds that, change it for a different value. Let's say 1.
I tried to do this by loops but it doesn't seem to be a good way to solve that or I messed it up. Because for some array it works, for some it does not.
Here's my code:
function searching(array) {
for (i = 0; i < array.length; i++) {
let horizontal = array[i][0];
let howMany = 1;
for (j = 1; j < array[i].length; j++) {
if (horizontal === array[i][j]) {
howMany += 1;
horizontal = array[i][j];
if (howMany >= 3) {
for (d = j; d > j - howMany; d--) {
array[i][d] = 0;
}
}
} else {
horizontal = array[i][j];
howMany = 1;
}
}
}
for (v = 0; v < array.length; v++) {
let vertical = array[0][v];
let howMany = 1;
for (x = 1; x < array.length; x++) {
if (vertical === array[x][v]) {
howMany++;
vertical = array[x][v];
if (howMany >= 3) {
for (d = x; d > x - howMany; d--) {
array[d][v] = 0;
}
}
} else {
vertical = array[x][v];
howMany = 1;
}
}
}
}
The idea is to for example give array:
let array = [
[3, 4, 5, 6, 7],
[3, 4, 5, 6, 7],
[3, 4, 5, 5, 5],
[3, 5, 6, 7, 4]
]
And the result should be:
let result = [
[1, 1, 1, 6, 7],
[1, 1, 1, 6, 7],
[1, 1, 1, 1, 1],
[1, 5, 6, 7, 4]
]
Thanks in advance for any ideas how to solve it :) Greetings!
The problems with your current code are
(1) You're only checking individual rows and columns, when you need to be checking them both (eg, with [[2, 2], [2, 5]], when at the starting position [0][0], you need to look at both [0][1] (and its neighbors, if matching) as well as [1][0] (and its neighbors, if matching).
(2) You're not actually checking for adjacency at the moment, you're just counting up the total number of matching elements in a particular row or column.
Iterate over all indicies of the array. If an index has already been checked, return early. Recursively search for neighbors to that index, and if at least 3 matching in total are found, set them all to 1. Put all matching neighbors in the checked set to avoid checking them again (even if there were less than 2 adjacent matches found total).
setAllAdjacentToOne([
[3, 4, 5, 6, 7],
[3, 4, 5, 6, 7],
[3, 4, 5, 5, 5],
[3, 5, 6, 7, 4]
]);
// all 9s stay, the rest get set to 1:
setAllAdjacentToOne([
[2, 2, 9, 7, 7],
[2, 9, 9, 9, 7],
[3, 4, 4, 5, 5],
[9, 4, 5, 5, 9]
]);
function setAllAdjacentToOne(input) {
const output = input.map(subarr => subarr.slice());
const checked = new Set();
const getKey = (x, y) => `${x}_${y}`;
const width = input[0].length;
const height = input.length;
const getAllAdjacent = (x, y, numToFind, matches = []) => {
if (x >= width || x < 0 || y >= height || y < 0) {
return matches;
}
const key = getKey(x, y);
if (!checked.has(key) && input[y][x] === numToFind) {
checked.add(key);
matches.push({ x, y });
getAllAdjacent(x + 1, y, numToFind, matches);
getAllAdjacent(x - 1, y, numToFind, matches);
getAllAdjacent(x, y + 1, numToFind, matches);
getAllAdjacent(x, y - 1, numToFind, matches);
}
return matches;
};
output.forEach((innerRowArr, y) => {
innerRowArr.forEach((num, x) => {
const allAdjacent = getAllAdjacent(x, y, num);
if (allAdjacent.length <= 2) {
return;
}
allAdjacent.forEach(({ x, y }) => {
output[y][x] = 1;
});
});
});
console.log(JSON.stringify(output));
}
I didn't understand the question at first...
So this is my code:
let array = [
[3, 4, 5, 6, 7],
[3, 4, 5, 6, 7],
[3, 4, 5, 5, 5],
[3, 5, 6, 7, 4]
];
function replace(arr, target = 1) {
let needToChange = []; // save the index to change
const numbers = [3, 4, 5, 6, 7];
const m = arr.length; // m rows
const n = arr[0].length; // n columns
let mi = 0;
let ni = 0;
// search in row
for (mi = 0; mi < m; mi++) {
for (let x = 0; x < numbers.length; x++) {
const num = numbers[x]; // number to search
let counter = 0; // counter for this number in row mi
let tempArr = [];
for (ni = 0; ni < n; ni++) {
const currentNum = arr[mi][ni];
if (currentNum === num) {
counter++;
tempArr.push([mi, ni]);
}
}
if (counter >= 3) {
needToChange = needToChange.concat(tempArr);
}
}
}
// search in column
for (ni = 0; ni < n; ni++) {
for (let x = 0; x < numbers.length; x++) {
const num = numbers[x]; // number to search
let counter = 0; // counter for this number in row mi
let tempArr = [];
for (mi = 0; mi < m; mi++) {
const currentNum = arr[mi][ni];
if (currentNum === num) {
counter++;
tempArr.push([mi, ni]);
}
}
if (counter >= 3) {
needToChange = needToChange.concat(tempArr);
}
}
}
// replace
needToChange.forEach(([i, j]) => {
array[i][j] = target;
});
}
replace(array);
array.forEach(row => {
console.log(row.join(', '));
})
Dear all I'm trying to find non repeated value in an array using javascript.I have written some code but it not working properly ..can you guys tell me where is the problem.thanks.
var arr = [-1, 2, 5, 6, 2, 9, -1, 6, 5, -1, 3];
var n = arr.length;
var result = '';
function nonrep() {
for (var i = 0; i < n; i++) {
var j;
for (j = 0; j < n; j++)
if (i != j && arr[i] == arr[j]) {
result = arr[i];
break;
}
if (j == n)
return arr[i];
}
return result;
}
console.log(nonrep())
There is possibly a more neat approach to this solution, but this works as expected by filtering the array and compare it's current value with the array items itself (expect current item's index value).
const sampleArray = [1,2,3,7,2,1,3];
const getNonDuplicatedValues = (arr) =>
arr.filter((item,index) => {
arr.splice(index,1)
const unique = !arr.includes(item)
arr.splice(index,0,item)
return unique
})
console.log("Non duplicated values: " , ...getNonDuplicatedValues(sampleArray))
Some changes:
Move all variable declarations inside of the function.
Use a function parameter for the handed over array, keep the function pure.
Declare all needed variables at top of the function in advance.
Take an array as result array unique.
Check i and j and if equal continue the (inner) loop.
Check the value at i and j and exit the (inner) loop, because a duplicate is found.
Take the check at the end of the inner loop and check the index j with the length of the array l, and if equal push the value to unique.
Use a single return statement with unique array at the end of the outer loop.
function getUnique(array) {
var l = array.length,
i, j,
unique = [];
for (i = 0; i < l; i++) {
for (j = 0; j < l; j++) {
if (i === j) {
continue;
}
if (array[i] === array[j]) {
break;
}
}
if (j === l) {
unique.push(array[i]);
}
}
return unique;
}
console.log(getUnique([-1, 2, 5, 6, 2, 9, -1, 6, 5, -1, 3]));
Another solution could be to check if indexOf and lastIndexOf returns the same value. Then you found a unique value.
var array = [-1, 2, 5, 6, 2, 9, -1, 6, 5, -1, 3],
unique = array.filter((v, i) => array.indexOf(v) === array.lastIndexOf(v));
console.log(unique);
You could first use reduce to get one object with count for each number element and then filter on Object.keys to return array of non-repeating numbers.
var arr=[-1,2,5,6,2,9,-1,6,5,-1,3];
var obj = arr.reduce((r, e) => (r[e] = (r[e] || 0) + 1, r), {});
var uniq = Object.keys(obj).filter(e => obj[e] == 1).map(Number)
console.log(uniq)
Solution with for loop.
var arr = [-1, 2, 5, 6, 2, 9, -1, 6, 5, -1, 3];
var uniq = [];
for (var i = 0; i < arr.length; i++) {
for (var j = 0; j < arr.length; j++) {
if (arr[i] == arr[j] && i != j) break;
else if (j == arr.length - 1) uniq.push(arr[i])
}
}
console.log(uniq)
Another simple approach
var arr = [1,1,2,3,3,4,4,5];
let duplicateArr = [];
var repeatorCheck = (item) => {
const currentItemCount = arr.filter(val => val=== item).length;
if(currentItemCount > 1) duplicateArr.push(item);
return currentItemCount;
}
var result = arr.filter((item,index) => {
var itemRepeaterCheck = !duplicateArr.includes(item) && repeatorCheck(item);
if(itemRepeaterCheck === 1){
return item;
}
});
console.log(result);
let arr = [1, 2, 1, 3, 3, 5];
function nonRepeatableNo(arr) {
let val = []
for (let i = 0; i < arr.length; i++) {
let count = 0;
for (let j = 0; j < arr.length; j++) {
if (arr[i] === arr[j]) {
count += 1
}
}
if (count === 1) {
val.push(arr[i])
}
}
console.log(val)
}
nonRepeatableNo(arr)
const arr = [-1, 2, 5, 6, 2, 9, -1, 6, 5, -1, 3];
const non_repeating = arr.filter(num => arr.indexOf(num) === arr.lastIndexOf(num))
console.log(non_repeating)
Filtering only unique elements according to OP request:
This uses for loops, as requested. It returns an array containing only elements appearing once in the original array.
var arr = [-1, 2, 5, 6, 2, 9, -1, 6, 5, -1, 3];
var n = arr.length;
var result = [];
function nonrep() {
for (var i = 0; i < n; i++) {
for (var j=0 ; j < n; j++)
if (i!=j && arr[i]==arr[j])
break;
if(j==n)
result.push(arr[i]);
}
return result;
}
console.log(nonrep())
var arr1 = [45, 4,16,25,45,4,16, 9,7, 16, 25];
var arr=arr1.sort();
console.log(arr);
var str=[];
arr.filter(function(value){
if( arr.indexOf(value) === arr.lastIndexOf(value))
{ str.push(value);
console.log("ntttttttttttttnnn" +str)
}// how this works ===============A
})
O/P
7,9
Please try the below code snippet.
var arr = [-1, 2, 5, 6, 2, 9, -1, 6, 5, -1, 3];
var uniqArr = [];
for (var i = 0; i < arr.length; i++) {
for (var j = 0; j < arr.length; j++) {
if (arr[i] == arr[j] && i != j) break;
else if (j == arr.length - 1){
uniqArr.push(arr[i])
}
}
}
console.log(uniqArr)
this ES6 code worked for me :
a.map(c=>a.filter(b=>c==b)).filter(e=>e.length<2).reduce((total, cur)=> total.concat(cur), [])
Here is a working method with loops.
var arr = [-1,2,5,6,2,9,-1,6,5,-1,3];
var len = arr.length;
const result = arr
.filter(value=>{
var count=0;
for(var i=0;i<len;i++)
{
if(arr[i]===value)
count++;
}
return count===1;
})
console.log(result);
const sampleArr = [-1, 2, 5, 6, 2, 9, -1, 6, 5, -1, 3];
function getUnique(arr){
const result=[]
const obj={}
for(let i=0;i<arr.length;i++){
if(!obj[arr[i]]){
obj[arr[i]]=true
result.push(arr[i])
}else{
const index= result.indexOf(arr[i])
if(index!==-1){
result.splice(result.indexOf(arr[i]),1)
}
}
}
return result
}
const uniqueArr= getUnique(sampleArr)
console.log(uniqueArr)
Here is the solution..
var x = [1,1,2,3,2,4]
var res = []
x.map(d => {
if(res.includes(d)) {
// remove value from array
res = res.filter((a) => a!=d)
} else {
// add value to array
res.push(d)
}
})
console.log(res) // [3,4]
//without using any filter also with minimum complexity
const array = [1 , 2, 3, 4, 2, 3, 1, 6, 8,1,1 ];
const unique = new Set();
const repetedTreses = new Set();
for(let i=0; i<array.length; i++) {
if(!unique.has(array[i]) && !repetedTreses.has(array[i])){
unique.add(array[i]);
}else{
repetedTreses.add(array[i]);
unique.delete(array[i]);
}
}
let uniqueElements=[...unique];
console.log(uniqueElements);
You can use filter and indexOf for that:
console.log(
[-1, 2, 5, 6, 2, 9, -1, 6, 5, -1, 3].filter((v, i, a) => a.indexOf(v, i + 1) === -1 )
);
i am trying to write a javascript code to find the first duplicate number from an arrayn for which the second occurrence has the minimal index.I have already written the function and it works fine for almost all given arrays except for the test case given below.
Input:
a: [1, 1, 2, 2, 1]
Output:
2
Expected Output:
1
The javascript code is given below
function firstDuplicate(a) {
var firstIndex = "";
var isMatch = false;
for (var i = 0; i <= a.length; i++) {
for (var j = i + 1; j <= a.length; j++) {
alert(a[i] + "," + a[j]);
if (a[i] === a[j]) {
firstIndex = j;
isMatch = true;
break;
}
}
}
if (isMatch)
return a[firstIndex];
else
return -1;
}
the program is bugged using alert statement inside the second for loop.I found that the value of a[i] and a[j] is same in the first execution of the loop itself yet the if condition right below fails. I wonder how this happens and can anyone plaese explain me why this happens?
You should only set firstIndex if it is lower than its current value.
Also, your loop bounds are incorrect. They should have < instead of <=.
console.log(firstDuplicate([1, 1, 2, 2, 1])); // 1
console.log(firstDuplicate([2, 3, 3, 1, 5, 2])); // 3
console.log(firstDuplicate([2, 4, 3, 5, 1])); // -1
function firstDuplicate(a) {
var firstIndex = Infinity;
var isMatch = false;
for (var i = 0; i < a.length; i++) {
for (var j = i + 1; j < a.length; j++) {
// ---------------vvvvvvvvvvvvvvvvv
if (a[i] === a[j] && j < firstIndex) {
firstIndex = j;
isMatch = true;
break;
}
}
}
if (isMatch)
return a[firstIndex];
else
return -1;
}
Here's another way to write it:
console.log(firstDuplicate([1, 1, 2, 2, 1])); // 1
console.log(firstDuplicate([2, 3, 3, 1, 5, 2])); // 3
console.log(firstDuplicate([2, 4, 3, 5, 1])); // -1
function firstDuplicate(a) {
let idx = Infinity;
for (const [i, n] of a.entries()) {
const dupIdx = a.indexOf(n, i+1);
if (dupIdx !== -1 && dupIdx < idx) {
idx = dupIdx;
}
}
return isFinite(idx) ? a[idx] : -1;
}
You could take a single loop approach with using a hash table for indicating visited items.
function firstDuplicate(array) {
var hash = Object.create(null),
i = 0,
l = array.length,
item;
while (i < l) {
item = array[i];
if (hash[item]) {
return item;
}
hash[item] = true;
i++;
}
return -1;
}
console.log(firstDuplicate([1, 1, 2, 2, 1])); // 1
console.log(firstDuplicate([2, 3, 3, 1, 5, 2])); // 3
console.log(firstDuplicate([2, 4, 3, 5, 1])); // -1
Solution in Javascript:
function solution(a) {
for (let i = 0; i < a.length; i++)
if (a.indexOf(a[i]) !== i) return a[i];
return -1;
}
console.log(solution([2, 1, 3, 5, 3, 2])); // 3
console.log(solution([2, 2])); // 2
console.log(solution([2, 4, 3, 5, 1])); // -1
I'm working on an algorithm to return the difference of any pair of numbers, such that the larger integer in the pair occurs at a higher index (in the array) than the smaller integer.
Examples...
Array: [2, 3, 10, 2, 4, 8, 1]
Solution: 10 - 2 = 8
Output: 8
Array: [7, 9, 5, 6, 3, 2]
Solution: 9 - 7 = 2
Output: 2
Here is what I have but it doesn't work for all tests...
var a = [22, 2, 4, 5, 6, 444, 1, 666];
// declare variables
var minNumber = a[0], // initilize to first element
maxNumber = a[0], // --- ^
minNumberIndex = 0, // min index
maxNumberIndex = a.length - 1; // max index
// loop through each element in array
for(i = 0; i < a.length; i++) {
// find min
if (a[i] < minNumber && i < maxNumberIndex) {
minNumber = a[i];
minNumberIndex = i;
}
// find max
if (a[i] >= maxNumber && i > minNumberIndex) {
maxNumber = a[i];
maxNumberIndex = i;
}
}
// return results
console.log("max: \t" + maxNumber);
console.log("min: \t" + minNumber + "index: " + minNumberIndex);
console.log(maxNumber - minNumber);
Please help!
O(n) solution:
function maxDifference(arr) {
let maxDiff = -1;
let min = arr[0];
for (let i = 0; i < arr.length; i++) {
if (arr[i] > min && maxDiff < arr[i] - min) {
maxDiff = arr[i] - min;
}
if (arr[i] < min) {
min = arr[i];
}
}
return maxDiff;
}
console.log(maxDifference([1, 2, 3])); //2
console.log(maxDifference(3, 2, 1)); //-1
console.log(maxDifference([2, 3, 10, 2, 4, 8, 1])); //8
console.log(maxDifference([7, 9, 5, 6, 3, 2])); //2
console.log(maxDifference([22, 2, 4, 5, 6, 444, 1, 666])); //665
console.log(maxDifference([7, 9, 5, 6, 3, 2])); //2
console.log(maxDifference([666, 555, 444, 33, 22, 23])); //1
console.log(maxDifference([2, 3, 10, 2, 4, 8, 1])); //8
let MaxDifference = arr => {
let maxDiff = null;
for(let x = 0; x < arr.length; x++){
for(let y = x+1; y < arr.length; y++){
if(arr[x] < arr[y] && maxDiff < (arr[y] - arr[x])){
maxDiff = arr[y] - arr[x]
}
}
}
return maxDiff === null ? -1 : maxDiff;
}
You can have two arrays. Lets call them minlr and maxrl.
minlr - Where minlr[i] stores the minimum value till index i when going from left to right in the original array.
maxrl - Where maxrl[i] stores the maximum value till index i when going from right to left in the original array.
Once you have these 2 arrays, you iterate the arrays and find the max difference between maxrl[i] and minlr[i].
In your above examples:
minlr = {2,2,2,2,2,2,1};
maxrl = {10,10,10,8,8,8,1};
So the answer in this case would be 10 - 2 = 8.
minlr = {7,7,5,5,3,2};
maxrl = {9,9,6,6,3,2};
So the answer in this case would be 9 - 7 = 2
es6 version:
var a = [2, 3, 10, 2, 4, 8, 1];
var min = a[0];
var max = a[a.length-1];
var init = [[0,min], [a.length -1,max]];
var r = a.reduce((
res, e,i
)=>{
var [[mini, min ], [maxi ,max]] = res;
var t = res;
if(e<min && i<maxi){
t = [[i, e ], [maxi ,max]];
}
if(e>=max && i>mini){
t = [[mini, min ], [i ,e]];
}
return t;
}, init);
console.log(r[1][1]-r[0][1]);
Is this ok? for each item in the array, it looks at earlier items and adds the difference to the internal 'diffs' array (if the current item is greater). I then return the the largest value within the diffs array.
var findMaxDiff = function(arr){
var diffs = [];
for(var i = 1; i < arr.length; i++){
for(var j = 0; j < i; j++){
if(arr[i] > arr[j]){
diffs.push(arr[i]-arr[j]);
}
}
}
return Math.max.apply( Math, diffs );
}
Looping through the array and using recursion like so:
function maxDifference(a){
var maxDiff = a[1] - a[0];
for(var i = 2; i<a.length-1; i++){
var diff = a[i] - a[0];
maxDiff = diff>maxDiff ? diff : maxDiff;
}
if(a.length>1){
a.shift();
var diff = maxDifference(a);
maxDiff = diff>maxDiff ? diff : maxDiff;
}
return maxDiff;
}
var x = [2, 3, 10, 2, 4, 8, 1];
maxDifference(x); // returns 8
x = [7, 9, 5, 6, 3, 2];
maxDifference(x) // returns 2
In linear time and constant memory:
function maxDiff (nums) {
var diff = 0, left = 0, right = 0, cur_right = 0, cur_left = 0;
for (var i = 0; i < nums.length; i++) {
if (nums[i] < nums[cur_left]) {
cur_left = i;
if (cur_left > cur_right) {
cur_right = cur_left;
}
}
if (nums[i] >= nums[cur_right]) {
cur_right = i;
}
if (nums[cur_right] - nums[cur_left] > diff) {
diff = nums[cur_right] - nums[cur_left];
right = cur_right;
left = cur_left;
}
}
return [diff, left, right];
}
If you're only interested in what the difference is, and not where the numbers occur, you don't need left and right.
var maxDiff = function() {
var list = Array.prototype.slice.call(arguments, 0)[0];
var start = new Date().getTime();
if((list !== null) && (toString.call(list) !== "[object Array]")) {
console.warn("not an array");
return;
}
var maxDiff = list[1] - list[0];
var min_element = list[0];
var i, j;
for(i = 1; i < list.length; i++) {
if(list[i] - min_element > maxDiff) {
maxDiff = list[i] - min_element;
}
if(list[i] < min_element) {
min_element = list[i];
}
}
var end = new Date().getTime();
var duration = end - start;
console.log("time taken:: " + duration + "ms");
return maxDiff;
};
maxdiff = 0;
a = [2, 3, 10, 2, 4, 8, 1]
for (i=a.length-1; i >= 0; i--) {
for (j=i-1; j >= 0; j--) {
if (a[i] < a[j] ) continue;
if (a[i] -a[j] > maxdiff) maxdiff = a[i] -a[j]
}
}
console.log(maxdiff || 'No difference found')
we can use es6 + es2020 latest feature to fix this issue
function maxDiff(arr) {
var diff=0
if(arr?.length) diff=arr?.length?Math.max(...arr)-Math.min(...arr):0
return diff;
}
console.log(maxDiff([1, 2, 3])); //2
console.log(maxDiff([3, 2, 1])); //2
console.log(maxDiff([2, 3, 10, 2, 4, 8, 1])); //9
console.log(maxDiff([7, 9, 5, 6, 3, 2])); //7
console.log(maxDiff([22, 2, 4, 5, 6, 444, 1, 666])); //665
console.log(maxDiff([7, 9, 5, 6, 3, 2])); //7
console.log(maxDiff([666, 555, 444, 33, 22, 23])); //644
console.log(maxDiff([-0, 1, 2, -3, 4, 5, -6])); //11
console.log(maxDiff([2])); //0
console.log(maxDiff([])); //0
var a = [22, 2, 4, 5, 6, 444, 1, 666];
function solution(a) {
const max = Math.max.apply(null,a);
const min = Math.min.apply(null,a);
const diff = max-min;
return diff
}
console.log(solution(a))
you actually don't need any looping, just use Math.max(), Math.min(), and [].indexOf() to do the heavy-lifting for you:
function findDiff(a){
var max=Math.max.apply(0, a),
slot=a.lastIndexOf(max),
min=Math.min.apply(0, a.slice(0, slot));
if(a.length && !slot && !min-.153479 )return findDiff(a.slice(1));
return max-min;
}
//ex: findDiff([7, 9, 5, 6, 3, 2]) == 2
//ex: findDiff([666, 555, 444 , 33, 22, 23]) == 1
//ex: findDiff([2, 3, 10, 2, 4, 8, 1]) == 8
If I have an array of [1, 2, 3, 5, 10, 9, 8, 9, 10, 11, 7] and wanted to find each case of 3 consecutive numbers (whether ascending or descending), how would I do that?
Second part would be then to alert an array with the index of each of these sequences.
For ex. the previous array would return [0,4,6,7].
So far I have this... which is a rough start
var arr = [1, 2, 3, 5, 10, 9, 8, 9, 10, 11, 7];
var results = [];
for (var i = 1; i < arr.length; i++) {
if ((arr[i] - arr[i-1] != 1) && (arr[i] - arr[i+1] != 1)) {
results.push(arr[i]);
}
}
alert(results);
Thanks for the help!
Thanks for the math.abs pointer. This is what I ended up doing:
var array = [1, 2, 3, 5, 10, 9, 8, 9, 10, 11, 7];
var indexes = [];
for(var i=0; i < array.length; i++) {
var diff = array[i+1] - array[i];
if(Math.abs(diff)==1 && array[i+1]+diff == array[i+2]) {
indexes.push(i);
}
}
alert(indexes);
It'd be interesting to know the context of this task as well... Anyway, here's my solution:
var arr = [1, 2, 3, 5, 10, 9, 8, 9, 10, 11, 7];
var results = [];
var limit = arr.length - 1;
var sequence = 0;
for (var i = 0; i < limit; ++i) {
var diff = arr[i+1] - arr[i];
if (sequence && sequence === diff) {
results.push(i-1);
continue;
}
sequence = (diff === 1 || diff === -1) // or ... Math.abs(diff) === 1
? diff
: 0;
}
console.log(results);
The idea is simple: we don't need to compare two neighbors twice. ) It's enough to raise a kind of sequence flag if this comparation starts a sequence, and lower it if no sequence is there.
This is a very literal approach to your question - I have only checked forwards numbers, but adding reverse would be done almost in the same way
var arr = [1, 2, 3, 4, 10, 9, 8, 9, 10, 11, 7];
var results = [];
for (var i = 0; i < arr.length; i++) {
// if next element is one more, and one after is two more
if (arr[i+1] == arr[i]+1 && arr[i+2] == arr[i]+2){
// store the index of matches
results.push(i);
// loop through next numbers, to prevent repeating longer sequences
while(arr[i]+1 == arr[i+1])
i++;
}
}
console.log(results);
You need to look closely at your expression in your if statement.
It currently says:
If the difference between the current element and previous element is not 1, and
If the difference between the current element and next element is not 1
then it's a result.
So, on the face of it, that's an incorrect logical statement to determine if the current element is in the middle of a consecutive set of three.
In addition, this doesn't account for an ascending or descending set of three either.
Try figuring out, in words, what the condition would look like and go from there.
Some things to consider
I suggest you start going through the list from i = 2
Research Math.abs
This is I think a simpler way to do it. First check the average of the left and right number is equal to the middle, then check that the absolute value of either neighbor is one.
var arr = [1, 2, 3, 5, 10, 9, 8, 9, 10, 11, 7];
var indexes = [];
for(var i=1; i < arr.length; i++) {
if((arr[i-1]+arr[i+1]) / 2 == arr[i] && Math.abs(arr[i]-arr[i-1]) == 1) {
indexes.push(i-1);
}
}
alert(indexes);
var arr = [1, 2, 3, 5, 10, 9, 8, 9, 10, 11, 7];
var results = [];
for (var i = 0; i < arr.length - 2; i++) {
if ((arr[i+1] - arr[i] === 1) && (arr[i+2] - arr[i+1] === 1)) {
results.push({
i:i,
mode:'up',
arr:[arr[i],arr[i+1],arr[i+2]
});
}
if ((arr[i+1] - arr[i] === -1) && (arr[i+2] - arr[i+1] === -1)) {
results.push({
i:i,
mode:'down',
arr:[arr[i],arr[i+1],arr[i+2]
});
}
}
alert(results);