I have an object {"1": "a", "2": "b", "3": "c"}
How could I get max key?
I don't need a value, just key, so I would like to have 3 of type number
Use Object.keys to get all key values and from them get the largest using Math.max method with Function#apply method.
var obj = {
"1": "a",
"2": "b",
"3": "c"
};
console.log(
Math.max.apply(null, Object.keys(obj))
)
// or with ES6 spread syntax
console.log(
Math.max(...Object.keys(obj))
)
Here is an alternative using reduce() on the keys:
var data = {"1": "a", "2": "b", "3": "c"};
var max = Object.keys(data).reduce(function(a, b) {
return a > +b ? a : +b;
});
console.log(max);
var data = {"1": "a", "2": "b", "3": "c"}
var max = 0;
for (var property in data) {
max = (max < parseFloat(property)) ? parseFloat(property) : max;
}
console.log(max);
Related
I have a simple bitmask, 3 ("011" in base 2) which denotes that I should extract array[0] and array[1] but not array[2]
What is an efficient way to do this?
Ultimately, I'm generating a new array with values that passed a .filter
Something like this:
var bitmask = 37, // "100101"
array = ["a", "b", "c", "d", "e", "f"];
var array2 = array.filter((value, index) => {
// do something with bitmask and index to return true
});
// array2 should be ["a", "c", "f"];
Expanding on your original example you can do this:
var bitmask = 37, // "100101"
array = ["a", "b", "c", "d", "e", "f"];
var array2 = array.filter((value, index) => {
// do something with bitmask and index to return true
return bitmask & (1 << index);
});
// array2 should be ["a", "c", "f"];
console.log(array2);
var bitmask = 5, idx=0;
// Loop till bitmask reach 0, works when bitmask >= 0
// If you want to sure instead of implicit type converting (from number to boolean)
// Just change it to while(bitmask >= 0)
while(bitmask){
// If the rightmost bit is 1, take the array[index]
if(bitmask & 1) console.log("take arr["+idx+"]");
// Shift right by 1 bit, say 5 = 101, this will make the number become 2 = 10
bitmask>>=1;
// Increase the index
idx++;
}
Using your own example, here is the code works:
var bitmask = 37, // "100101"
array = ["a", "b", "c", "d", "e", "f"],
idx = 0;
var array2 = [];
while(bitmask){
if(bitmask & 1) array2.push(array[idx]);
bitmask>>=1;
idx++;
}
Simply use some bit operation to loop it. As it is looping bit by bit, I think it is the fastest you can get
One way to do this is cast your number into a binary string, then check if the index of the bitmask is "1" inside your filter.
var bitmask = (37).toString(2), // "100101"
array = ["a", "b", "c", "d", "e", "f"];
var array2 = array.filter((value, index) => {
if(bitmask[index] == "1") return value;
});
console.log(array2);
So given a simple json object
[
{"a": 1},
{"b": 2},
{"c": 3},
{"d": 4}
]
and an array like this
var arr = ["A", "B", "C"];
I want to write the most efficient function to match the lower case keys with their upper case counter parts and replace them with the uppercase letters, I started by turning the array into a object so I wont have to iterate over and over again, but Im stuck. Can someone please show me how they would handle this in the most efficient way?
Without further information on your amount of keys/possible keys, trying to make a generic solution would be like this:
var arr = [
{"a": 1},
{"b": 2},
{"c": 3},
{"d": 4}
]
var match = ["A", "B", "C"];
var objMatch = {}
for(var i=0;i<match.length;i++) objMatch[match[i].toLowerCase()] = match[i] // pass it to an object for efficient matching
for(var i=0;i<arr.length;i++){
for(var key in arr[i]){ // check if we need to replace the key
if(objMatch.hasOwnProperty(key)){
var temp = arr[i][key] // keep old value
delete arr[i][key] // delete key
arr[i][objMatch[key]] = temp // set new key with same old value
}
}
}
console.log(arr)
From what i understand from your question
var arrayOne = [
{"a": 1},
{"b": 2},
{"c": 3},
{"d": 4}
];
var arrayTwo = ["A", "B", "C"];
var tempArray = {};
$.each(arrayOne, function(key,value){
for(arrayOneKey in value){
$.each(arrayTwo, function(index,vl) {
if(vl.toLowerCase() == arrayOneKey.toLowerCase()){
tempArray[vl]=key+1;
}
});
}
});
console.log(tempArray);
var a=[
{"a": 1},
{"b": 2},
{"c": 3},
{"d": 4}
];
var arr = ["A", "B", "C"];
Define a method in Object's prototype chain to rename Object keys:
Object.prototype.changeKey = function (oName, nName) {
if (oName == nName) {
return this;
}
if (this.hasOwnProperty(oName)) {
this[nName] = this[oName];
delete this[oName];
}
return this;
};
Then find the key which matches the elements of array, then change it:
for(var i=0;i<arr.length;i++){
for(key in a[i]){
if(key === arr[i].toLowerCase()){a[i].changeKey (key,arr[i])}
}
}
Here is a fiddle
Don't make things complicated. Use map and return a new array:
function transform(arr, keys) {
return arr.map(function(el) {
var obj = {};
var key = Object.keys(el)[0];
var uc = key.toUpperCase();
obj[keys.indexOf(uc) > -1 ? uc : key] = el[key];
return obj;
});
}
transform(input, arr);
DEMO
You could use an helper object and loop throu all items and all keys.
var arr0 = [{ "a": 1 }, { "b": 2 }, { "c": 3 }, { "d": 4 }],
arr1 = ["A", "B", "C"],
obj = Object.create(null);
arr1.forEach(function (a) {
obj[a.toUpperCase()] = a;
});
arr0.forEach(function (a) {
Object.keys(a).forEach(function (k) {
var v = a[k];
if (k.toUpperCase() in obj) {
delete a[k];
a[obj[k.toUpperCase()]] = v;
}
});
});
document.write('<pre>' + JSON.stringify(arr0, 0, 4) + '</pre>');
Suppose we have the following:
var o = {"1": 1, "2": 2, "5": 5};
And I wanted to turn it into what I would get if I did:
var o = []; o[1] = 1, o[2] = 2, o[5] = 5;
How could I do this?
Try this:
var o = { ... }; // your object
var oArr = [];
for (var i in o) {
if (parseInt(i) == i) {
oArr[parseInt(i)] = o[i];
}
}
Notice that it won't accept keys that are non numeric.
If you have a proper length property, it's really easy:
var o = {"1": 1, "2": 2, "5": 5, 'length' : 6};
o = Array.prototype.slice.call(o); // [undefined, 1, 2, undefined, undefined, 5]
If you don't have the length property, you can compute it:
var o = {"1": 1, "2": 2, "5": 5};
o.length = Object.keys(o).reduce(function(max,key){
return isNaN(key) ? max : Math.max(max, +key);
},-1) + 1;
o = Array.prototype.slice.call(o); // [undefined, 1, 2, undefined, undefined, 5]
One thing to note, though, when you access a property of an object, it is always converted to a string, so the following will work for your example, even if o is not an array:
var o = {"1": 1, "2": 2, "5": 5};
o[1] // 1
o[2] // 2
o[5] // 5
o[0] // undefined
You should not be doing that,
1. You are not sure about how big the maximum index value can be.
2. There could be lots of gaps, those indexes in the array will be null,
So, just use a string conversion of the index number and look it up in the same object.
var o = {"1": 1, "2": 2, "5": 5};
var index = 5;
o[index.toString()] // gives 5
In javascript, is there an easy way to merge 2 arrays as if shuffling a deck of cards?
For example:
[ "1", "2", "3" ] +
[ "a", "b", "c" ]
=> [ "1", "a", "2", "b", "3", "c" ]
This action is typically called "zip".
Underscore.js has an implementation of it:
var a1 = [ "1", "2", "3" ];
var a2 = [ "a", "b", "c" ];
var zipped = _.zip(a1, a2);
If you want a random order, you can use shuffle:
var shuffled = _.shuffle(a1.concat(a2));
var arr1 = ["1", "2", "3"];
var arr2 = ["a", "b", "c"];
You can just loop through the arrays and create a new one. This example assumes that arr1 and arr2 are the same length.
var result = (function(a, b){
for(var i = 0, result = []; i < a.length; i++)
result.push(a[i], b[i]);
return result;
})(arr1, arr2);
// result == ["1", "a", "2", "b", "3", "c"]
You can't do it without iterating, but you can hide the iteration behind some array functions.
var a = [ "1", "2", "3" ];
var b = [ "a", "b", "c" ];
// only works if a and b have the same length
var c = a.concat(b).map(function(item, index, arr){
return index % 2 ? arr[arr.length/2 + (index+1)/2 - 1] : arr[index/2];
});
console.log(c);
You can create a closure that can be used as an array for reading (i.e. c(i) returns i-th element of result):
c = function(i){ return [a, b][i & 1][i >> 1]; };
or, probably more efficient, as
c = function(i){ return (i & 1) ? b[i >> 1] : a[i >> 1]; };
The nice thing of this approach is that you don't build all elements at once, but you will just get the element from the original arrays only if requested.
This also allows using functions instead of arrays for a and b:
c = function(i){ return (i & 1) ? b(i >> 1) : a(i >> 1); };
I have an object and an array:
m = { "1": ["2", "3"], "6": ["4", "5"] };
var p = ["1", "6"];
I have a for loop:
for (var i = 0; i < p.length; i++) {
// Return an array that is the value of a key in m, for each key specified in p
var array = m[p[i]];
// do stuff with array
}
Any reason why the above does not work? array is still undefined after the for loop runs.
Also I think p should be [1,6] as well? Since you're using it to reference the keys in the object m.
The error happens because you have this declaration:
var p = ["1","2"];
But the m properties are:
m = {
"1": [2,3],
"6": [4,5]
}
So in p[1] makes your program read m["2"] but it doesn't have a "2" property.
Use this code instead:
var p = ["1","6"];
Your declaration of m = { "1": ["2", "3"], "6", ["4", "5"] }; gives syntax error for me. I assume you mean m = { "1": ["2", "3"], "6": ["4", "5"] };.
p.length is 2, so you have 2 iterations of the loop. In first iteration values of your expressions are:
i = 0
p[i] = "1"
m[p[i]] = m["1"] = ["2", "3"]
In second loop:
i = 1
p[i] = "2"
m[p[i]] = m["2"] (undefined)
You have only m["1"] and m["6"], no m["2"]. That's why array is undefined in the last iteration. So it remains undefined after the loop.
You may correct m declaration as following:
m = { "1": ["2", "3"], "2": ["4", "5"] };
Now you will get array = ["4", "5"] after the loop.
I can advise you not to store integers in strings. Use 2 instead of "2". Otherwise it can cause errors in the future. For example, 2 + 2 = 4 and "2" + "2" = "22". If you have "2" from some other code, use parseInt to convert it to a normal number.
Also, you don't have to create p variable with list of keys. You can simply use for..in loop to iterate through keys of your object:
m = { 1: [2, 3], 2: [4, 5] };
for(i in m) {
var array = m[i];
//do stuff
}
Keep in mind that for..in doesn't guarantee to preserve the order of keys. However, all existing implementations of for..in do preserve the order.