find pairs which sum equal to given value with o(n) complexcity - javascript

I have an Array which contains numbers. I want to find the pair of the number which sums equal to given value with o(n) complexity.
let data = [5,8,9,6];
var x = {};
function findSum(arr, sum){
data.forEach(function(item){
if(item > sum){
return null
}
var diff = sum - item;
x[item] = diff
})
console.log(x);
}
findSum(data, 7);
Working with O(n2) complexity.
let data = [2, 4, 11, 3, 5, 8, 9, 1, 6, 5]
function findSum(arr, sum) {
let sortArray = arr.sort(function(a, b) {
return a - b
});
let findIndex = arr.indexOf(arr.find(function(item) {
return item >= sum
}))
let iterateValues = sortArray.slice(0, findIndex);
var pairs = [];
console.log(iterateValues)
iterateValues.forEach(function(value, index) {
let getDiff = sum - value;
let findDiff = iterateValues.find(function(diff, index) {
return diff === getDiff
});
if (findDiff) {
let firstPair = value.toString()
let secondPair = findDiff.toString();
let merge = firstPair + ',' + secondPair;
pairs.push(merge)
}
})
console.log(pairs)
}
findSum(data, 7);

Try the following, it takes O(n) time to find the pair whose sum is equal to given value:
let data = [5,8,9,6];
var sum = 17;
var map = {};
var found = false;
for(var i = 0; i < data.length; i++){
map[data[i]] = i;
}
for(var i = 0; i < data.length; i++){
if(map[sum - data[i]] && map[sum - data[i]] != i){
found = true;
console.log(data[map[sum - data[i]]] + " "+data[i]);
break;
}
}
if(!found)
console.log("No pair found");

Using a Set and for of loop
function findSum(arr, sum) {
let set = new Set(),
res = null;
for (let n of arr) {
const diff = sum - n;
if (diff && set.has(diff)) {
res = [diff, n]
break;
}
set.add(n);
}
return res ? res.join(' + ') + ' = ' + sum : 'No Matches for ' + sum
}
let data = [2, 4, 11, 3, 5, 8, 9, 1, 6, 5];
console.log(findSum(data, 6))
console.log(findSum(data, 7))
console.log(findSum(data, 8))
console.log(findSum(data, 22))

Related

How to split array into equal parts based on values?

Input Arr=[1,2,3,4,5,6,7,8,9,10]
Expected output:-
Arr1 = [1,2,3,4,5,6,7] = 28
Arr2 = [8,9,10] = 27
The sum of arrays should be almost the same..
It can also be 3 or more parts
How to achieve this via custom function?
let Arr = [1,2,3,4,5,6,7,8,9,10]
const numberOfParts = 2
function SplitArr(Array, Parts){
/* ... */
}
let result = SplitArr(Arr,numberOfParts)
/* result should be [[1,2,3,4,5,6,7],[8,9,10]] */
/* output can be in any format as long as it can get the parts */
I think you can't do that directly by JS functions.
You have to create a custom function to achieve this.
I have considered dividing the array into 2 equal parts.
You can't always split the array equally. Here in this array, you can't partition array into more than 2 subparts, otherwise it will give more than 3 parts as some of the elements are present there having sum more than the partitioned Sum.
Note: I treated the array to be sorted, otherwise it depends on the usecase.
Note: I have updated the old implementation based on the updated question requirement
let arr=[1,2,3,4,5,6,7,8,9,10]
function splitArrayEqually(arr, parts=2){
//get the total sum of the array
let sum = arr.reduce((currentSum, value) => currentSum+value ,0);
//get the half sum of the array
let partitionedSum = Math.ceil(sum/parts);
let start=0, end=0, currentSum=0;
let splittedArray=[];
//get the index till which the sum is less then equal partitioned sum
while(end < arr.length){
if(currentSum+arr[end] > partitionedSum){
splittedArray.push(arr.slice(start,end));
start = end; //start new window from current index
currentSum = 0; //make sum =0
}
//add current end index to sum
currentSum += arr[end];
end++;
}
splittedArray.push(arr.slice(start));
return splittedArray;
}
splitted = splitArrayEqually(arr,3);
console.log(splitted)
let Arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
const numberOfParts = 3
function sumOfArray(arr) {
if (arr) {
if (arr.length > 0) {
let sum = 0
for (let i = 0; i < arr.length; i++) sum += arr[i]
return sum
} else {
return 0
}
} else {
return 0
}
}
function SplitArr(Array, Parts) {
let lastIndex = 0
let result = []
function getReamingSum(arr) {
let psum = sumOfArray(Array.slice(lastIndex)) / Parts
console.log('psum ' + psum)
return psum + Parts
}
let psum = getReamingSum(Array)
for (let j = 0; j < Parts; j++) {
let total = 0
for (let i = 0; i < Array.length; i++) {
if (i >= lastIndex) {
total += Array[i]
if (total < psum || j === Parts - 1) {
if (result[j]?.length > 0) {
result[j].push(Array[i])
} else {
let arr = []
arr.push(Array[i])
result[j] = arr
}
lastIndex = i + 1
}
}
}
}
return result
}
let result = SplitArr(Arr, numberOfParts)
console.log(result)
Assuming the array isn't sorted,using a 2D array, with each sub array with sum almost equal to (sum of array / n).
let arr = [9,2,10,4,5,6,7,8,1,3]
arr.sort(function(a, b) { return a - b; });
const sum = arr.reduce((a, b) => a + b, 0);
const n = 2;
const result = [];
let s = 0;
let j = 0;
result[j] = [];
for(let i=0; i<arr.length; i++){
if(s <= Math.floor(sum/n)){
result[j].push(arr[i]);
s +=arr[i];
}
else{
s = 0;
j = j + 1;
result[j] = [];
result[j].push(arr[i]);
}
}
console.log(result)
O/P:
[ [1, 2, 3, 4,5, 6, 7], [ 8, 9, 10 ] ]
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const splitArray = (arr,parts) => {
const totalSum = arr.reduce((acc, item) => {
acc += item;
return acc;
}, 0)
const splitSum = Math.floor(totalSum / parts);
const arrObj = arr.reduce((acc, item,index) => {
acc.sum = acc.sum || 0;
acc.split = acc.split || {};
const pointer = Math.floor(acc.sum / splitSum);
//console.log(item,acc.sum, splitSum, pointer);
acc.split[pointer] = acc.split[pointer] || [];
acc.split[pointer].push(item);
acc.splitSum = splitSum;
acc.sum += item;
return acc;
}, {})
return arrObj;
}
console.log(splitArray(arr,2).split)
You're better off making a custom function:
let currentTotal = 0
let tempList = []
Arr.forEach(val => {
if (val >= 27) {
// push tempList to a new array
tempList = [];
currentTotal = val;
} else {
tempList.push(val);
currentTotal += val;
}
})

JavaScript: calculate the average of an odd number

I want to count the average value of the odd numbers from a list of numbers. I have a starting code to count the average, but I don't know how can I choose only the odd numbers from the list?
Here is my code:
var numberArray = [1,2,3,4,5,6], thisTotal=0,thisAverage=0;
for (var i=0; i<numberArray.length; i++) {
thisTotal += numberArray[i];
}
thisAverage = (thisTotal/numberArray.length);
alert(thisAverage)
You can use a filter function to return only the odd numbers:
var oddArray = numberArray.filter(function(val) {
return val % 2 !== 0;
});
Full example:
var numberArray = [1, 2, 3, 4, 5, 6];
var thisTotal = 0;
var thisAverage = 0;
var oddArray = numberArray.filter(function(val) {
return val % 2 !== 0;
});
console.log(oddArray); // [1, 3, 5]
var thisTotal = oddArray.reduce(function(accumulator, currentValue) { return accumulator + currentValue;
});
console.log(thisTotal); // 1 + 3 + 5 => 9
var thisAverage = thisTotal / oddArray.length;
console.log(thisAverage); // 9 / 3 => 3
var numberArray=[1,2,3,4,5,6], thisAverage=0,oddlength=0;
for(var i=0;i<numberArray.length;i++)
{
if(numberArray[i]%2!==0){
thisAverage+=numberArray[i];
oddlength++;
}
}
thisAverage=(thisAverage/oddlength);
alert(thisAverage)
Well, you can get what you want by this.
var numberArray=[1,2,3,4,5,6], thisTotal=0,thisAverage=0;
for(var i=0; i < 3; i++) {
thisTotal += numberArray[i * 2];
thisAverage= (thisTotal/numberArray.length);
}
console.log(thisAverage);
or if you want general solution, use this.
var numberArray=[1,2,3,4,5,6,7,8,...on and on], thisTotal=0,thisAverage=0;
for(var i=0; i < Math.ceil(numberArray.length() / 2); i++) {
thisTotal += numberArray[i * 2];
thisAverage= (thisTotal/numberArray.length);
}
console.log(thisAverage);
hope my code be helpful :)
You can use the function reduce to add and count.
var numberArray = [1, 2, 3, 4, 5, 6],
result = numberArray.reduce((a, n) => {
if (n % 2 !== 0) {
a.sum += n;
a.count++;
}
return a;
}, {sum: 0, count: 0}),
average = result.sum / result.count;
console.log(average);
Assuming the numbers are in an array, you can do this:
var numbers = [1, 2, 3, 4, 5, 6];
var info = numbers.filter(function(n) { return n % 2 !== 0})
.reduce(function(acc, item) {
return {sum: acc.sum + item, count: acc.count + 1}
}, {sum: 0, count: 0});
var avg = info.sum / info.count;
This example uses filter and reduce methods, which are declarative and more clear.
filter returns a new array with the items for which the function returns true, and then reduce, for each item, updates an 'accumulator'. The accumulator can be anything, and in this case is an object with the sum of the numbers and their count. For each item, we add add the current number to the sum property and add 1 to count. Finally, we just devide sum by count and done.
var acc = 0, oddCount = 0;
for(var i = 0; i < numberArray.length; i++) {
if(numberArray[i] % 2 !== 0) {
acc += numberArray[i];
oddCount++;
}
}
return acc / oddCount;
You can create a new array and store odd values in that array and after that you can apply your logic to that array.
var a=[1,2,3,4,5,6,10,11];
var ar=[];
for (var i = 0; i < a.length; i++) {
if(a[i] % 2 !== 0) {
ar.push(a[i]);
}
}
console.log(ar);
var numberArray=[1,2,3,4,5,6,7,8];
var count = 0;
var result = 0;
for (let i = 0; i <= (numberArray.length-1); i++)
{
if (numberArray[i] % 2 != 0)
{
result += numberArray[i];
count++;
}
}
alert(result / count);

Parse array to equal intervals JS

I want to parse my array to 4 equal intervals. For example, array [12, 48] parse to 4 intervals [12,21], [21, 30], [30, 39], [39, 48]. I could only parse my Array to pairs (code here). But I don't know how to do what I want.
var arrayTest = [];
for (var i = 0; i < 1000; i++) arrayTest[i] = i;
var ab = [2, 6];
start = ab[0];
finish = ab[1];
var ab_new = [];
for (var i = start; i <= finish; i++) ab_new[i]= arrayTest[i];
var output = [];
for (var i = start; i < ab_new.length - 1; ++i) {
output[i] = [];
output[i].push(ab_new[i]);
output[i].push(ab_new[i + 1]);
}
console.log(output);
My output is:
[ , , [ 2, 3 ], [ 3, 4 ], [ 4, 5 ], [ 5, 6 ] ]
You can calculate the interval and use it to map in an array of length 4 over the index.
const ab = [12, 48]
const start = ab[0];
const end = ab[1];
const interval = (end - start) / 4;
const out = Array(4)
.fill()
.map((_, i) => [start + i*interval, start + (i + 1) * interval])
You could take a length for each interval and add the lenght to the start value for each part.
function getIntervals(range, parts) {
var result = [],
length = (range[1] - range[0]) / parts,
i = 0,
t;
while (i < parts) {
t = range[0] + i * length;
result.push([t, t + length]);
i++;
}
return result;
}
console.log(getIntervals([12, 48], 4));
Another approach by using length as increment value.
function getIntervals(range, parts) {
var result = [],
length = (range[1] - range[0]) / parts,
i = range[0];
while (i < range[1]) {
result.push([i, i += length]);
}
return result;
}
console.log(getIntervals([12, 48], 4));
ES6
function getIntervals(range, parts) {
var l = (range[1] - range[0]) / parts,
i = range[0];
return Array.from({ length: parts}, _ => [i, i += l]);
}
console.log(getIntervals([12, 48], 4));
let a=[12,48]; // your array
var interval = 4;
var diff =(a[1]-a[0])/interval; // calculating the diff
var start = a[0]; //start value
var b =[]; // output array
for(var i=0; i<interval; i++){
b.push( [start, start + diff]); // for each iteration push start and start+diff
start+=diff;
}
console.log(b)
function sep4(inp){
var diff = inp[1] - inp[0]
var add = diff/4
var ar = []
for(i = 1; i < 5; i++){
ar.push([inp[0], inp[0] + (add * i)])
}
return ar
}
// just call the function as sep4([12, 48])

Pair of elements from a specified array whose sum equals a specific target number

I am in mid of my JavaScript session. Find this code in my coding exercise. I understand the logic but I didn't get this map[nums[x]] condition.
function twoSum(nums, target_num) {
var map = [];
var indexnum = [];
for (var x = 0; x < nums.length; x++)
{
if (map[nums[x]] != null)
// what they meant by map[nums[x]]
{
index = map[nums[x]];
indexnum[0] = index+1;
indexnum[1] = x+1;
break;
}
else
{
map[target_num - nums[x]] = x;
}
}
return indexnum;
}
console.log(twoSum([10,20,10,40,50,60,70],50));
I am trying to get the Pair of elements from a specified array whose sum equals a specific target number. I have written below code.
function arraypair(array,sum){
for (i = 0;i < array.length;i++) {
var first = array[i];
for (j = i + 1;j < array.length;j++) {
var second = array[j];
if ((first + second) == sum) {
alert('First: ' + first + ' Second ' + second + ' SUM ' + sum);
console.log('First: ' + first + ' Second ' + second);
}
}
}
}
var a = [2, 4, 3, 5, 6, -2, 4, 7, 8, 9];
arraypair(a,7);
Is there any optimized way than above two solutions? Can some one explain the first solution what exactly map[nums[x]] this condition points to?
Using HashMap approach using time complexity approx O(n),below is the following code:
let twoSum = (array, sum) => {
let hashMap = {},
results = []
for (let i = 0; i < array.length; i++){
if (hashMap[array[i]]){
results.push([hashMap[array[i]], array[i]])
}else{
hashMap[sum - array[i]] = array[i];
}
}
return results;
}
console.log(twoSum([10,20,10,40,50,60,70,30],50));
result:
{[10, 40],[20, 30]}
I think the code is self explanatory ,even if you want help to understand it,let me know.I will be happy enough to for its explanation.
Hope it helps..
that map value you're seeing is a lookup table and that twoSum method has implemented what's called Dynamic Programming
In Dynamic Programming, you store values of your computations which you can re-use later on to find the solution.
Lets investigate how it works to better understand it:
twoSum([10,20,40,50,60,70], 50)
//I removed one of the duplicate 10s to make the example simpler
In iteration 0:
value is 10. Our target number is 50. When I see the number 10 in index 0, I make a note that if I ever find a 40 (50 - 10 = 40) in this list, then I can find its pair in index 0.
So in our map, 40 points to 0.
In iteration 2:
value is 40. I look at map my map to see I previously found a pair for 40.
map[nums[x]] (which is the same as map[40]) will return 0.
That means I have a pair for 40 at index 0.
0 and 2 make a pair.
Does that make any sense now?
Unlike in your solution where you have 2 nested loops, you can store previously computed values. This will save you processing time, but waste more space in the memory (because the lookup table will be needing the memory)
Also since you're writing this in javascript, your map can be an object instead of an array. It'll also make debugging a lot easier ;)
function twoSum(arr, S) {
const sum = [];
for(let i = 0; i< arr.length; i++) {
for(let j = i+1; j < arr.length; j++) {
if(S == arr[i] + arr[j]) sum.push([arr[i],arr[j]])
}
}
return sum
}
Brute Force not best way to solve but it works.
Please try the below code. It will give you all the unique pairs whose sum will be equal to the targetSum. It performs the binary search so will be better in performance. The time complexity of this solution is O(NLogN)
((arr,targetSum) => {
if ((arr && arr.length === 0) || targetSum === undefined) {
return false;
} else {
for (let x = 0; x <=arr.length -1; x++) {
let partnerInPair = targetSum - arr[x];
let start = x+1;
let end = (arr.length) - 2;
while(start <= end) {
let mid = parseInt(((start + end)/2));
if (arr[mid] === partnerInPair) {
console.log(`Pairs are ${arr[x]} and ${arr[mid]} `);
break;
} else if(partnerInPair < arr[mid]) {
end = mid - 1;
} else if(partnerInPair > arr[mid]) {
start = mid + 1;
}
}
};
};
})([0,1,2,3,4,5,6,7,8,9], 10)
function twoSum(arr, target) {
let res = [];
let indexes = [];
for (let i = 0; i < arr.length - 1; i++) {
for (let j = i + 1; j < arr.length; j++) {
if (target === arr[i] + arr[j] && !indexes.includes(i) && !indexes.includes(j)) {
res.push([arr[i], arr[j]]);
indexes.push(i);
indexes.push(j);
}
}
}
return res;
}
console.log('Result - ',
twoSum([1,2,3,4,5,6,6,6,6,6,6,6,6,6,7,8,9,10], 12)
);
Brute force.
const findTwoNum = ((arr, value) => {
let result = [];
for(let i= 0; i< arr.length-1; i++) {
if(arr[i] > value) {
continue;
}
if(arr.includes(value-arr[i])) {
result.push(arr[i]);
result.push(value-arr[i]);
break;;
}
}
return result;
});
let arr = [20,10,40,50,60,70,30];
const value = 120;
console.log(findTwoNum(arr, value));
OUTPUT : Array [50, 70]
function twoSum(arr){
let constant = 17;
for(let i=0;i<arr.length-2;i++){
for(let j=i+1;j<arr.length;j++){
if(arr[i]+arr[j] === constant){
console.log(arr[i],arr[j]);
}
}
}
}
let myArr = [2, 4, 3, 5, 7, 8, 9];
function getPair(arr, targetNum) {
for (let i = 0; i < arr.length; i++) {
let cNum = arr[i]; //my current number
for (let j = i; j < arr.length; j++) {
if (cNum !== arr[j] && cNum + arr[j] === targetNum) {
let pair = {};
pair.key1 = cNum;
pair.key2 = arr[j];
console.log(pair);
}
}
}
}
getPair(myArr, 7)
let sumArray = (arr,target) => {
let ar = []
arr.forEach((element,index) => {
console.log(index);
arr.forEach((element2, index2) => {
if( (index2 > index) && (element + element2 == target)){
ar.push({element, element2})
}
});
});
return ar
}
console.log(sumArray([8, 7, 2, 5, 3, 1],10))
Use {} hash object for storing and fast lookups.
Use simple for loop so you can return as soon as you find the right combo; array methods like .forEach() have to finish iterating no matter what.
And make sure you handle edges cases like this: twoSum([1,2,3,4], 8)---that should return undefined, but if you don't check for !== i (see below), you would erroneously return [4,4]. Think about why that is...
function twoSum(nums, target) {
const lookup = {};
for (let i = 0; i < nums.length; i++) {
const n = nums[i];
if (lookup[n] === undefined) {//lookup n; seen it before?
lookup[n] = i; //no, so add to dictionary with index as value
}
//seen target - n before? if so, is it different than n?
if (lookup[target - n] !== undefined && lookup[target - n] !== i) {
return [target - n, n];//yep, so we return our answer!
}
}
return undefined;//didn't find anything, so return undefined
}
We can fix this with simple JS object as well.
const twoSum = (arr, num) => {
let obj = {};
let res = [];
arr.map(item => {
let com = num - item;
if (obj[com]) {
res.push([obj[com], item]);
} else {
obj[item] = item;
}
});
return res;
};
console.log(twoSum([2, 3, 2, 5, 4, 9, 6, 8, 8, 7], 10));
// Output: [ [ 4, 6 ], [ 2, 8 ], [ 2, 8 ], [ 3, 7 ] ]
Solution In Java
Solution 1
public static int[] twoNumberSum(int[] array, int targetSum) {
for(int i=0;i<array.length;i++){
int first=array[i];
for(int j=i+1;j<array.length;j++){
int second=array[j];
if(first+second==targetSum){
return new int[]{first,second};
}
}
}
return new int[0];
}
Solution 2
public static int[] twoNumberSum(int[] array, int targetSum) {
Set<Integer> nums=new HashSet<Integer>();
for(int num:array){
int pmatch=targetSum-num;
if(nums.contains(pmatch)){
return new int[]{pmatch,num};
}else{
nums.add(num);
}
}
return new int[0];
}
Solution 3
public static int[] twoNumberSum(int[] array, int targetSum) {
Arrays.sort(array);
int left=0;
int right=array.length-1;
while(left<right){
int currentSum=array[left]+array[right];
if(currentSum==targetSum){
return new int[]{array[left],array[right]};
}else if(currentSum<targetSum){
left++;
}else if(currentSum>targetSum){
right--;
}
}
return new int[0];
}
function findPairOfNumbers(arr, targetSum) {
var low = 0, high = arr.length - 1, sum, result = [];
while(low < high) {
sum = arr[low] + arr[high];
if(sum < targetSum)
low++;
else if(sum > targetSum)
high--;
else if(sum === targetSum) {
result.push({val1: arr[low], val2: arr[high]});
high--;
}
}
return (result || false);
}
var pairs = findPairOfNumbers([1,2,3,4,4,5], 8);
if(pairs.length) {
console.log(pairs);
} else {
console.log("No pair of numbers found that sums to " + 8);
}
Simple Solution would be in javascript is:
var arr = [7,5,10,-5,9,14,45,77,5,3];
var arrLen = arr.length;
var sum = 15;
function findSumOfArrayInGiven (arr, arrLen, sum){
var left = 0;
var right = arrLen - 1;
// Sort Array in Ascending Order
arr = arr.sort(function(a, b) {
return a - b;
})
// Iterate Over
while(left < right){
if(arr[left] + arr[right] === sum){
return {
res : true,
matchNum: arr[left] + ' + ' + arr[right]
};
}else if(arr[left] + arr[right] < sum){
left++;
}else{
right--;
}
}
return 0;
}
var resp = findSumOfArrayInGiven (arr, arrLen, sum);
// Display Desired output
if(resp.res === true){
console.log('Matching Numbers are: ' + resp.matchNum +' = '+ sum);
}else{
console.log('There are no matching numbers of given sum');
}
Runtime test JSBin: https://jsbin.com/vuhitudebi/edit?js,console
Runtime test JSFiddle: https://jsfiddle.net/arbaazshaikh919/de0amjxt/4/
function sumOfTwo(array, sumNumber) {
for (i of array) {
for (j of array) {
if (i + j === sumNumber) {
console.log([i, j])
}
}
}
}
sumOfTwo([1, 2, 3], 4)
function twoSum(args , total) {
let obj = [];
let a = args.length;
for(let i = 0 ; i < a ; i++){
for(let j = 0; j < a ; j++){
if(args[i] + args[j] == total) {
obj.push([args[i] , args[j]])
}
}
}
console.log(obj)}
twoSum([10,20,10,40,50,60,70,30],60);
/* */

Get smallest and highest number to the right and left to my value

Please let me know if there is a faster, more elegant way to get this result:
I have an array of numbers, and once set a value i should get smallest and highest number to the right and left to my value.
For example if I have: [1,2,3,4,6,7,8,9] and a value is 5,
my numbers will be:1, 4,6,9
if value is 4
my numbers will be 1,4,4,9
My horrible code is:
var arr = [1, 8, 2, 3, 9, 5, 4, 6, 7];
var result1 = [];
var result2 = [];
var goal = 5;
for (a = 0; a < arr.length; a++) {
if (arr[a] < goal) {
result1.push(arr[a])
} else if (arr[a] === goal) {
result1.push(arr[a]);
result2.push(arr[a]);
} else {
result2.push(arr[a]);
}
};
var count1 = result1[0];
for (x = 0; x < result1.length; x++) {
if (result1[x] < count1) {
count1 = result1[x]
}
};
var count11 = result1[0];
for (xx = 0; xx < result1.length; xx++) {
if (result1[xx] > count11) {
count11 = result1[xx]
}
};
var count2 = result2[0];
for (y = 0; y < result2.length; y++) {
if (result2[y] > count2) {
count2 = result2[y]
}
};
var count22 = result2[0];
for (yy = 0; yy < result2.length; yy++) {
if (result2[yy] < count22) {
count22 = result2[yy]
}
};
console.log(count1 + ' ' + count11 + ' ' + count22 + ' ' + count2)
You can simplify your code a lot by using a few mighty methods: Array::filter and Math.min/max:
var arr = [1, 8, 2, 3, 9, 5, 4, 6, 7];
var goal = 5;
var result1 = arr.filter(function(x) { return x <= goal });
var result2 = arr.filter(function(x) { return x >= goal });
var count1 = Math.min.apply(Math, result1);
var count11 = Math.max.apply(Math, result1);
var count2 = Math.min.apply(Math, result2);
var count22 = Math.max.apply(Math, result2);
Assuming the array is sorted always,
var array = [1, 2, 3, 4, 6, 7, 8, 9],
number = 5,
pivot, small, large;
for (var i = 0, len = array.length; i < len; i += 1) {
if (array[i] >= number) {
pivot = i;
break;
}
}
if (pivot > 0) {
small = [array[0], array[pivot - 1]];
large = [array[pivot], array[len - 1]];
console.log(small, large);
} else {
console.log("Not possible");
}
Well I came up with the following solution. Considering that array is always sorted
function GetVals(arr, pivot){
return arr.reduce(function(t,v,i,arr){
if (v < pivot) {
if (typeof t.LMin == "undefined" || t.LMin > v)
t.LMin = v;
if (typeof t.LMax == "undefined" || t.LMax < v)
t.LMax = v;
} else if (v > pivot) {
if (typeof t.RMin == "undefined" || t.RMin > v)
t.RMin = v;
if (typeof t.RMax == "undefined" || t.RMax < v)
t.RMax = v;
}
return t;
}, {});
}
The returned result will have 4 properties, LMin LMax for left min and max and RMin RMax for right min maxes respectively.
if LMin and LMax are equal, this means there is only 1 value from the left (the same rule for the right)
if LMin and LMax are undefined, this means that there are no values from the left less than pivot.
EDIT
Although I realize the question has been answered and another response selected, I at least wanted to update my code to a tested version. FWIW, it works, and does not rely on nor assume a sorted array.
function minmax(valueArray, targetValue) {
var i = 0;
var minBelow;
var maxBelow;
var minAbove;
var maxAbove;
while (i < valueArray.length) {
var currentValue = valueArray[i];
if (currentValue < targetValue) {
if (currentValue < minBelow || !minBelow) {
minBelow = currentValue;
}
if (currentValue > maxBelow || !maxBelow) {
maxBelow = currentValue;
}
}
if (currentValue > targetValue) {
if (currentValue < minAbove || !minAbove) {
minAbove = currentValue;
}
if (currentValue > maxAbove || !maxAbove) {
maxAbove = currentValue;
}
}
i++;
}
return {
minBelow: minBelow,
maxBelow: maxBelow,
minAbove: minAbove,
maxAbove: maxAbove
};
}
function test() {
alert('In test');
var foo = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var bar = minmax(foo, 5);
alert(bar.minBelow + ","+ bar.maxBelow + "," + bar.minAbove + "," + bar.maxAbove);
}

Categories

Resources