Related
Let's say I have the following 2 Arrays:
let a = [5,5,5,5,0]
let b = [5,5,5,5,0]
Assuming that both arrays has the same length:
I want to get a value from an element of one Array and add the +1 itself and to other remaining elements. If the the picked value is still bigger than zero, then it should also continue adding it to elements of other array from starting index.
Example_1: If I pick a[2] then the outcome should be:
a = [5,5,1,6,1] // a[2] became 0 after picking 5, then in each remaining element we add +1 and continue to next array.
b = [6,6,5,5,0]
Example_2: Or If I pick b[3] from initial arrays, then the outcome should be:
a = [6,6,6,5,0] // b[3] became 0 after picking 5, then in each remaining element we add +1 and move to next array until our value becomes zero
b = [5,5,5,1,1]
Here is my attempt:
let pickedValue = a[2]
for (let index = 2; index < a.length; index++) {
if (pickedValue > 0) {
a[index] += 1
pickedValue--
}
}
for (let index = 0; index < pickedValue; index++) {
if (pickedValue > 0) {
b[index] += 1
pickedValue--
}
}
Can we do this in more dynamic way with maybe one loop?
You just need to iterate through both arrays. The chosen array should be iterated from the target + 1 up to its lenght, and the other array, from 0 up the target.
You can see that I directly put a 1 to the chosen array at index target, instead of put a 0 and add +1.
(Also use some regex in order to catch the number between the brackets, from this SO answer)
let a = [5,5,5,5,0]
let b = [5,5,5,5,0]
const ans = prompt("Pick an element (e.g `a[2]` or `b[3]`)");
const [chosenArray, otherArray] = ans[0] === 'a' ? [a, b] : [b, a];
const target = parseInt(ans.match(/(?<=\[).+?(?=\])/), 10);
chosenArray[target] = 1;
for (let i = target + 1; i < chosenArray.length; ++i)
++chosenArray[i];
for (let i = 0; i < target; ++i)
++otherArray[i];
console.log(a, b)
You could tkae an object with same named properties of arrays and hand over target key and index and then update until no more value is to disperse.
const
update = (source, target, index) => {
const keys = Object.keys(source);
let value = source[target][index];
source[target][index] = 0;
while (value--) {
source[target][index++]++;
if (index === source[target].length) {
index = 0;
target = keys[(keys.indexOf(target) + 1) % keys.length];
}
}
return source;
};
console.log(update({ a: [5, 5, 5, 5, 0], b: [5, 5, 5, 5, 0] }, 'a', 2));
console.log(update({ a: [5, 5, 5, 5, 0], b: [5, 5, 5, 5, 0] }, 'b', 3));
.as-console-wrapper { max-height: 100% !important; top: 0; }
I found this JavaScript algorithm excercise:
Question:
From a unsorted array of numbers 1 to 100 excluding one number, how will you find that number?
The solution the author gives is:
function missingNumber(arr) {
var n = arr.length + 1,
sum = 0,
expectedSum = n * (n + 1) / 2;
for (var i = 0, len = arr.length; i < len; i++) {
sum += arr[i];
}
return expectedSum - sum;
}
I wanted to try and make it so you can find multiple missing numbers.
My solution:
var someArr = [2, 5, 3, 1, 4, 7, 10, 15]
function findMissingNumbers(arr) {
var missingNumbersCount;
var missingNumbers = [];
arr.sort(function(a, b) {
return a - b;
})
for(var i = 0; i < arr.length; i++) {
if(arr[i+1] - arr[i] != 1 && arr[i+1] != undefined) {
missingNumbersCount = arr[i+1] - arr[i] - 1;
for(j = 1; j <= missingNumbersCount; j++) {
missingNumbers.push(arr[i] + j)
}
}
}
return missingNumbers
}
findMissingNumbers(someArr) // [6, 8, 9, 11, 12, 13, 14]
Is there a better way to do this? It has to be JavaScript, since that's what I'm practicing.
You could use a sparse array with 1-values at indexes that correspond to values in the input array. Then you could create yet another array with all numbers (with same length as the sparse array), and retain only those values that correspond to an index with a 1-value in the sparse array.
This will run in O(n) time:
function findMissingNumbers(arr) {
// Create sparse array with a 1 at each index equal to a value in the input.
var sparse = arr.reduce((sparse, i) => (sparse[i]=1,sparse), []);
// Create array 0..highest number, and retain only those values for which
// the sparse array has nothing at that index (and eliminate the 0 value).
return [...sparse.keys()].filter(i => i && !sparse[i]);
}
var someArr = [2, 5, 3, 1, 4, 7, 10, 15]
var result = findMissingNumbers(someArr);
console.log(result);
NB: this requires EcmaScript2015 support.
The simplest solution to this problem
miss = (arr) => {
let missArr=[];
let l = Math.max(...arr);
let startsWithZero = arr.indexOf(0) > -1 ? 0 : 1;
for(i = startsWithZero; i < l; i++) {
if(arr.indexOf(i) < 0) {
missArr.push(i);
}
}
return missArr;
}
miss([3,4,1,2,6,8,12]);
Something like this will do what you want.
var X = [2, 5, 3, 1, 4, 7, 10, 15]; // Array of numbers
var N = Array.from(Array(Math.max.apply(Math, X)).keys()); //Generate number array using the largest int from X
Array.prototype.diff = function(a) {
return this.filter(function(i) {return a.indexOf(i) < 0;}); //Return the difference
};
console.log(N.diff(X));
Option 1:
1. create a binary array
2. iterate over input array and for each element mark binary array true.
3. iterate over binary array and find out numbers of false.
Time complexity = O(N)
Space complexity = N
Option 2:
Sort input array O(nLogn)
iterate over sorted array and identify missing number a[i+1]-a[i] > 0
O(n)
total time complexity = O(nlogn) + O(n)
I think the best way to do this without any iterations for a single missing number would be to just use the sum approach.
const arr=[1-100];
let total=n*(n+1)/2;
let totalarray=array.reduce((t,i)=>t+i);
console.log(total-totalarray);
You can try this:
let missingNum= (n) => {
return n
.sort((a, b) => a - b)
.reduce((r, v, i, a) =>
(l => r.concat(Array.from({ length: v - l - 1 }, _ => ++l)))(a[i - 1]),
[]
)
}
console.log(missingNum([1,2,3,4,10]));
Solution to find missing numbers from unsorted array or array containing duplicate values.
Array.prototype.max = function() {
return Math.max.apply(null, this);
};
var array1 = [1, 3, 4, 7, 9];
var n = array1.length;
var totalElements = array1.max(); // Total count including missing numbers. Can use max
var d = new Uint8Array(totalElements)
for(let i=0; i<n; i++){
d[array1[i]-1] = 1;
}
var outputArray = [];
for(let i=0; i<totalElements; i++) {
if(d[i] == 0) {
outputArray.push(i+1)
}
}
console.log(outputArray.toString());
My solution uses the same logic as trincot's answer
The time complexity is O(n)
const check_miss = (n) => {
let temp = Array(Math.max(...n)).fill(0);
n.forEach((item) => (temp[item] = 1));
const missing_items = temp
.map((item, index) => (item === 0 ? index : -1))
.filter((item) => item !== -1);
console.log(missing_items);
};
n = [5, 4, 2, 1, 10, 20, 0];
check_miss(n);
Is it possible for me to access every other item in an array? So basically, all items in positions 0, 2, 4, 6 etc.
Here's my code if it helps:
function pushToHash(key, value) {
for (var t = 0; t < value.length; t++) {
MQHash[key[t]] = value.slice(0, lineLength[t]);
}
}
So, I need to get every other value of lineLength. I only want this for lineLength, not key. I was thinking of doing a modulus, but wasn't sure how I'd implement it. Any ideas?
Thanks in advance!
You can use the index (second parameter) in the array filter method like this:
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// filter out all elements that are located at an even index in the array.
let x = arr.filter((element, index) => {
return index % 2 === 0;
})
console.log(x)
// [1, 3, 5, 7, 9]
If you just want this with lineLength and not with key, then add a second variable and use += when incrementing:
function pushToHash(key, value) {
for (var t = 0, x = 0; t < value.length; t++, x += 2) {
MQHash[key[t]] = value.slice(0, lineLength[x]);
}
}
(The power of the comma operator...)
How about for (var i = 1; i < array.length; i += 2)
Here is a function that will truncate an array every X elements (factor).
const truncateArray = (array: any[], factor: number): any[] => {
let lastNumber = 0;
return array.filter((element, index) => {
const shouldIncludeThisElement = index === lastNumber + factor ? true : false;
lastNumber = shouldIncludeThisElement ? index : lastNumber;
return shouldIncludeThisElement;
});
};
I have an object in javascript like this:
{ "a":4, "b":0.5 , "c":0.35, "d":5 }
Is there a fast way to get the minimum and maximum value among the properties without having to loop through them all? because the object I have is huge and I need to get the min/max value every two seconds. (The values of the object keeps changing).
Update: Modern version (ES6+)
let obj = { a: 4, b: 0.5 , c: 0.35, d: 5 };
let arr = Object.values(obj);
let min = Math.min(...arr);
let max = Math.max(...arr);
console.log( `Min value: ${min}, max value: ${max}` );
Original Answer:
Try this:
let obj = { a: 4, b: 0.5 , c: 0.35, d: 5 };
var arr = Object.keys( obj ).map(function ( key ) { return obj[key]; });
and then:
var min = Math.min.apply( null, arr );
var max = Math.max.apply( null, arr );
Live demo: http://jsfiddle.net/7GCu7/1/
There's no way to find the maximum / minimum in the general case without looping through all the n elements (if you go from, 1 to n-1, how do you know whether the element n isn't larger (or smaller) than the current max/min)?
You mentioned that the values change every couple of seconds. If you know exactly which values change, you can start with your previous max/min values, and only compare with the new ones, but even in this case, if one of the values which were modified was your old max/min, you may need to loop through them again.
Another alternative - again, only if the number of values which change are small - would be to store the values in a structure such as a tree or a heap, and as the new values arrive you'd insert (or update) them appropriately. But whether you can do that is not clear based on your question.
If you want to get the maximum / minimum element of a given list while looping through all elements, then you can use something like the snippet below, but you will not be able to do that without going through all of them
var list = { "a":4, "b":0.5 , "c":0.35, "d":5 };
var keys = Object.keys(list);
var min = list[keys[0]]; // ignoring case of empty list for conciseness
var max = list[keys[0]];
var i;
for (i = 1; i < keys.length; i++) {
var value = list[keys[i]];
if (value < min) min = value;
if (value > max) max = value;
}
You could try:
const obj = { a: 4, b: 0.5 , c: 0.35, d: 5 };
const max = Math.max.apply(null, Object.values(obj));
console.log(max) // 5
min and max have to loop through the input array anyway - how else would they find the biggest or smallest element?
So just a quick for..in loop will work just fine.
var min = Infinity, max = -Infinity, x;
for( x in input) {
if( input[x] < min) min = input[x];
if( input[x] > max) max = input[x];
}
// 1. iterate through object values and get them
// 2. sort that array of values ascending or descending and take first,
// which is min or max accordingly
let obj = { 'a': 4, 'b': 0.5, 'c': 0.35, 'd': 5 }
let min = Object.values(obj).sort((prev, next) => prev - next)[0] // 0.35
let max = Object.values(obj).sort((prev, next) => next - prev)[0] // 5
You can also try with Object.values
const points = { Neel: 100, Veer: 89, Shubham: 78, Vikash: 67 };
const vals = Object.values(points);
const max = Math.max(...vals);
const min = Math.min(...vals);
console.log(max);
console.log(min);
// Sorted
let Sorted = Object.entries({ "a":4, "b":0.5 , "c":0.35, "d":5 }).sort((prev, next) => prev[1] - next[1])
>> [ [ 'c', 0.35 ], [ 'b', 0.5 ], [ 'a', 4 ], [ 'd', 5 ] ]
//Min:
Sorted.shift()
>> [ 'c', 0.35 ]
// Max:
Sorted.pop()
>> [ 'd', 5 ]
You can use a reduce() function.
Example:
let obj = { "a": 4, "b": 0.5, "c": 0.35, "d": 5 }
let max = Object.entries(obj).reduce((max, entry) => entry[1] >= max[1] ? entry : max, [0, -Infinity])
let min = Object.entries(obj).reduce((min, entry) => entry[1] <= min[1] ? entry : min, [0, +Infinity])
console.log(max) // ["d", 5]
console.log(min) // ["c", 0.35]
Here's a solution that allows you to return the key as well and only does one loop. It sorts the Object's entries (by val) and then returns the first and last one.
Additionally, it returns the sorted Object which can replace the existing Object so that future sorts will be faster because it will already be semi-sorted = better than O(n). It's important to note that Objects retain their order in ES6.
const maxMinVal = (obj) => {
const sortedEntriesByVal = Object.entries(obj).sort(([, v1], [, v2]) => v1 - v2);
return {
min: sortedEntriesByVal[0],
max: sortedEntriesByVal[sortedEntriesByVal.length - 1],
sortedObjByVal: sortedEntriesByVal.reduce((r, [k, v]) => ({ ...r, [k]: v }), {}),
};
};
const obj = {
a: 4, b: 0.5, c: 0.35, d: 5
};
console.log(maxMinVal(obj));
To get the keys for max and min
var list = { "a":4, "b":0.5 , "c":0.35, "d":5 };
var keys = Object.keys(list);
var min = keys[0]; // ignoring case of empty list for conciseness
var max = keys[0];
var i;
for (i = 1; i < keys.length; i++) {
var value = keys[i];
if (list[value] < list[min]) min = value;
if (list[value] > list[max]) max = value;
}
console.log(min, '-----', max)
For nested structures of different depth, i.e. {node: {leaf: 4}, leaf: 1}, this will work (using lodash or underscore):
function getMaxValue(d){
if(typeof d === "number") {
return d;
} else if(typeof d === "object") {
return _.max(_.map(_.keys(d), function(key) {
return getMaxValue(d[key]);
}));
} else {
return false;
}
}
Using the lodash library you can write shorter
_({ "a":4, "b":0.5 , "c":0.35, "d":5 }).values().max();
var newObj = { a: 4, b: 0.5 , c: 0.35, d: 5 };
var maxValue = Math.max(...Object.values(newObj))
var minValue = Math.min(...Object.values(newObj))
obj.prototype.getMaxinObjArr = function (arr,propName) {
var _arr = arr.map(obj => obj[propName]);
return Math.max(..._arr);
}
This works for me:
var object = { a: 4, b: 0.5 , c: 0.35, d: 5 };
// Take all value from the object into list
var valueList = $.map(object,function(v){
return v;
});
var max = valueList.reduce(function(a, b) { return Math.max(a, b); });
var min = valueList.reduce(function(a, b) { return Math.min(a, b); });
If we are sorting date time value then follow the below described procedure
const Obj = {
"TRADE::Trade1": {
"dateTime": "2022-11-27T20:17:05.980Z",
},
"TRADE::Trade2": {
"dateTime": "2022-11-27T20:36:10.659Z",
},
"TRADE::Trade3": {
"dateTime": "2022-11-27T20:28:10.659Z",
}
}
const result = Object.entries(Obj).sort((prev, next) => new Date(prev[1].dateTime) - new Date(next[1].dateTime))
console.log(result)
I have an array Arr1 = [1,1,2,2,3,8,4,6].
How can I split it into two arrays based on the odd/even-ness of element positions?
subArr1 = [1,2,3,4]
subArr2 = [1,2,8,6]
odd = arr.filter (v) -> v % 2
even = arr.filter (v) -> !(v % 2)
Or in more idiomatic CoffeeScript:
odd = (v for v in arr by 2)
even = (v for v in arr[1..] by 2)
You could try:
var Arr1 = [1,1,2,2,3,8,4,6],
Arr2 = [],
Arr3 = [];
for (var i=0;i<Arr1.length;i++){
if ((i+2)%2==0) {
Arr3.push(Arr1[i]);
}
else {
Arr2.push(Arr1[i]);
}
}
console.log(Arr2);
JS Fiddle demo.
It would be easier using nested arrays:
result = [ [], [] ]
for (var i = 0; i < yourArray.length; i++)
result[i & 1].push(yourArray[i])
if you're targeting modern browsers, you can replace the loop with forEach:
yourArray.forEach(function(val, i) {
result[i & 1].push(val)
})
A functional approach using underscore:
xs = [1, 1, 2, 2, 3, 8, 4, 6]
partition = _(xs).groupBy((x, idx) -> idx % 2 == 0)
[xs1, xs2] = [partition[true], partition[false]]
[edit] Now there is _.partition:
[xs1, xs2] = _(xs).partition((x, idx) -> idx % 2 == 0)
var Arr1 = [1, 1, 2, 2, 3, 8, 4, 6]
var evenArr=[];
var oddArr = []
var i;
for (i = 0; i <= Arr1.length; i = i + 2) {
if (Arr1[i] !== undefined) {
evenArr.push(Arr1[i]);
oddArr.push(Arr1[i + 1]);
}
}
console.log(evenArr, oddArr)
I guess you can make 2 for loops that increment by 2 and in the first loop start with 0 and in the second loop start with 1
A method without modulo operator:
var subArr1 = [];
var subArr2 = [];
var subArrayIndex = 0;
var i;
for (i = 1; i < Arr1.length; i = i+2){
//for even index
subArr1[subArrayIndex] = Arr1[i];
//for odd index
subArr2[subArrayIndex] = Arr1[i-1];
subArrayIndex++;
}
//For the last remaining number if there was an odd length:
if((i-1) < Arr1.length){
subArr2[subArrayIndex] = Arr1[i-1];
}
Just for fun, in two lines, given that it's been tagged coffeescript :
Arr1 = [1,1,2,2,3,8,4,6]
[even, odd] = [a, b] = [[], []]
([b,a]=[a,b])[0].push v for v in Arr1
console.log even, odd
# [ 1, 2, 3, 4 ] [ 1, 2, 8, 6 ]
As a one-liner improvement to tokland's solution using underscore chaining function:
xs = [1, 1, 2, 2, 3, 8, 4, 6]
_(xs).chain().groupBy((x, i) -> i % 2 == 0).values().value()
filters is a non-static & non-built-in Array method , which accepts literal object of filters functions & returns a literal object of arrays where the input & the output are mapped by object keys.
Array.prototype.filters = function (filters) {
let results = {};
Object.keys(filters).forEach((key)=>{
results[key] = this.filter(filters[key])
});
return results;
}
//---- then :
console.log(
[12,2,11,7,92,14,5,5,3,0].filters({
odd: (e) => (e%2),
even: (e) => !(e%2)
})
)