I've a JavaScript object like this.
var obj = {
"set1": [1, 2, 3],
"set2": [4, 5, 6, 7, 8],
"set3": [9, 10, 11, 12]
};
This JavaScript object will be totally dynamic. So I need to get the key of this JavaScript object using some index method. Like
key[1] should return "set2"
So how can I get the ID of any index from the JavaScript object?
try this:
convert the json in a array:
var obj = {
"set1": [1, 2, 3],
"set2": [4, 5, 6, 7, 8],
"set3": [9, 10, 11, 12]
};
var arr = []
for (var key in obj) {
arr.push(obj[key]);
}
console.log(arr[1]);
or array of objects:
var obj = {
"set1": [1, 2, 3],
"set2": [4, 5, 6, 7, 8],
"set3": [9, 10, 11, 12]
};
var arr = []
for (var key in obj) {
arr.push({key:obj[key]});
}
console.log(arr[1]);
jsfiddle:https://jsfiddle.net/3yx8a12e/
You have these options (here's JSFiddle too):
var obj = {
"set1": [1, 2, 3],
"set2": [4, 5, 6, 7, 8],
"set3": [9, 10, 11, 12]
};
var sets = [];
for (var o in obj) {
if (obj.hasOwnProperty(o)) { //Thanks Magrangs for reference
sets.push(o);
};
};
//Or in modern browsers
//var sets = Object.keys(obj);
console.log(sets[1]);
You can use Object.keys(obj) to get an array of the keys of the object.
In your example, Object.keys(obj)[1] will return "set2".
Note that Object.keys is not supported in older browsers (see browser compatibility guide below):
Chrome - 5
Firefox (Gecko) - 4.0 (2.0)
Internet Explorer - 9
Opera - 12
Safari - 5
But you can polyfill it using the following code:
// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
if (!Object.keys) {
Object.keys = (function() {
'use strict';
var hasOwnProperty = Object.prototype.hasOwnProperty,
hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString'),
dontEnums = [
'toString',
'toLocaleString',
'valueOf',
'hasOwnProperty',
'isPrototypeOf',
'propertyIsEnumerable',
'constructor'
],
dontEnumsLength = dontEnums.length;
return function(obj) {
if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) {
throw new TypeError('Object.keys called on non-object');
}
var result = [], prop, i;
for (prop in obj) {
if (hasOwnProperty.call(obj, prop)) {
result.push(prop);
}
}
if (hasDontEnumBug) {
for (i = 0; i < dontEnumsLength; i++) {
if (hasOwnProperty.call(obj, dontEnums[i])) {
result.push(dontEnums[i]);
}
}
}
return result;
};
}());
}
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
function getKey(data, i){
var n = 0;
for(var k in data){
if(n == i) return k;
n++;
}
}
data - your js object, i - index of member
You can Retrieve All Keys this code
var obj = {
"set1": [1, 2, 3],
"set2": [4, 5, 6, 7, 8],
"set3": [9, 10, 11, 12]
};
var newary= [];
for (var x in obj) {
if (obj.hasOwnProperty(x)) { //Thanks Magrangs for reference
newary.push(x);
};
};
console.log(newary[1])
/*For Modern Browser use this code*/
// Retrieve All Keys of Object
Object.keys(obj);
// Retrieve Specific Keys of Object
Object.keys(obj)[1];
Related
function distinctUnion(arr, arr2) {
let merged = [...arr, ...arr2];
var result = [];
var map = {}
for (let i = 0; i < merged.length; i++) {
if (!map.hasOwnProperty(merged[i])) {
map[merged[i]] = true; // Line 3 --> if I remove this line, it prints duplicates
console.log('map', JSON.stringify(map, 2, null));
result.push(merged[i]);
}
}
return result;
}
let arr = [3, 4, 5, 6, 6, 4, 5, 8, 9, 10, 10];
let arr2 = [11, 11, 11, 4, 4, 4, 5, 5, 5, 6, 6, 6, 6];
console.log('unique ', JSON.stringify(distinctUnion(arr, arr2), 2, null));
All we are setting here is map[merged[i]] = true; for all keys in object
map {"3":true,"4":true,"5":true,"6":true,"8":true,"9":true,"10":true,"11":true}
then how result.push(merged[i]) has only unique values?
I mean to say merged[i] inside loop should still have all array values including duplicates right?
I am not able to understand the link between map[merged[i]] = true; and result.push(merged[i])
If you do not set the property to anything, map.hasOwnProperty(...) will spuriously return false for the next time that value is encountered, thus allowing duplicates. You don't need to set it to true, as it is just used to indicate the presence of a key; any value is fineāeven undefined!
function distinctUnion(arr, arr2) {
let merged = [...arr, ...arr2];
var result = [];
var map = {}
for (let i = 0; i < merged.length; i++) {
if (!map.hasOwnProperty(merged[i])) {
map[merged[i]] = undefined;
result.push(merged[i]);
}
}
return result;
}
let arr = [3, 4, 5, 6, 6, 4, 5, 8, 9, 10, 10];
let arr2 = [11, 11, 11, 4, 4, 4, 5, 5, 5, 6, 6, 6, 6];
console.log('unique ', JSON.stringify(distinctUnion(arr, arr2), 2, null));
To make your code works, you just need to replace map[merged[i]] = true; with map[merged[i]] = undefined;.
However, you can make your function more simplified as follows:
function distinctUnion(arr, arr2) {
let map = {};
[...arr, ...arr2].forEach((x)=>{map[x] = x});
return Object.values(map);;
}
let arr = [3, 4, 5, 6, 6, 4, 5, 8, 9, 10, 10];
let arr2 = [11, 11, 11, 4, 4, 4, 5, 5, 5, 6, 6, 6, 6];
console.log('Unique ', distinctUnion(arr, arr2));
I want to convert the below JSON format
let init = {
test1: [1, 2, 3, 4, 5],
test2: [6, 7, 8, 9, 10]
}
into this format using javascript native methods of array or object (supported in all browsers)
[{
test1: 1,
test2: 6
},{
test1: 2,
test2: 7
},{
test1: 3,
test2: 8
},{
test1: 4,
test2: 9
},{
test1: 5,
test2: 10
}]
I have tried with for loop and below is the code,
let keys = Object.keys(init);
let result = [];
for(let i = 0; i < keys.length; i++){
let key = keys[i];
for(let j = 0; j < init[key].length; j++){
if(i === 0){
let obj1 = {};
obj1[key] = init[key][j];
result.push(obj1);
}else{
let obj2 = result[j];
obj2[key] = init[key][j];
}
}
}
You could use Array.prototype.reduce() to do that.
Iterate on test1 array elements and push a new object to the array accumulator with test1 and test2 properties and their respective values.
let init = {
test1: [1, 2, 3, 4, 5],
test2: [6, 7, 8, 9, 10]
};
let keys = Object.keys(init);
let key1 = keys[0];
let key2 = keys[1];
let result = init[key1].reduce((acc, curr, i) => {
acc.push({
[key1]: curr,
[key2]: init[key2][i]
});
return acc;
}, []);
console.log(result);
As of now, reduce() method is supported in most of the modern browsers. For supporting all browsers, it is better to use for loop, but instead of Object.keys() iterate on object properties or use a polyfill.
let init = {
test1: [1, 2, 3, 4, 5],
test2: [6, 7, 8, 9, 10]
};
let keys = [];
for (let key in init) {
if (init.hasOwnProperty(key)) {
keys.push(key);
}
}
let key1 = keys[0];
let key2 = keys[1];
let result = [];
for (let i = 0; i < key1.length; i++) {
result.push({
[key1]: init[key1][i],
[key2]: init[key2][i]
});
}
console.log(result);
You could use a combination of for...in and Array.forEach to achieve this result in a few lines of code. If you wan't support for all browsers you can better use var instead of let though. https://caniuse.com/#search=let
var init = {
test1: [1, 2, 3, 4, 5],
test2: [6, 7, 8, 9, 10]
}
var result = []
for (var key in init) {
init[key].forEach(function (item, index) {
result[index] ? result[index][key] = item : result[index] = { [key]: item }
})
}
console.log(result)
You could maybe simplify this a bit more by initializing your result with empty objects, that would avoid using a ternary statement. That would look like this:
Disclaimer: This won't work in IE11 because of the lack of Array.fill() support
var init = {
test1: [1, 2, 3, 4, 5],
test2: [6, 7, 8, 9, 10]
}
var result = new Array(Object.keys(init)[0].length).fill().map(Object);
for (var key in init) {
init[key].forEach(function(item, index) {
result[index][key] = item
})
}
console.log(result)
If you do this make sure you don't create an array with Objects that are a reference to the same object in memory: Array.prototype.fill() with object passes reference and not new instance
I am trying to flatten any length of a nested array into a single array. Why it's showing array rather than array value?
function flatten(arr) {
var res = [];
for (var i = 0; i < arr.length; i++) {
if (toString.call(arr[i]) === "[object Array]") {
res.push(flatten(arr[i]));
} else {
res.push(arr[i]);
}
}
return res;
}
console.log(flatten([1, 2, [3, [4, 5, [6]]], 7, 8]));
// [1, 2, Array(2), 7, 8]
You are pushing to res the result of flatten, which is an array. Instead Array#concat the result of the inner flatten call to res, and assign the result to res.
Note: to identify an array, you can use Array#isArray.
function flatten(arr) {
var res = [];
for (var i = 0; i < arr.length; i++) {
if (Array.isArray(arr[i])) {
res = res.concat(flatten(arr[i]));
} else {
res.push(arr[i]);
}
}
return res;
}
console.log(flatten([1, 2, [3, [4, 5, [6]]], 7, 8])); // [1, 2, Array(2), 7, 8]
You can use concat instead of push and reduce instead of for loop.
const flatten = data => data.reduce((r, e) => {
return r = r.concat(Array.isArray(e) ? flatten(e) : e), r
}, [])
console.log(flatten([1, 2, [3, [4, 5, [6]]], 7, 8]))
You can use the flat() method on the array as follows.
function flatten(arr) {
return arr.flat(10) //the number in brackets are the depth level
}
console.log(flatten([1, 2, [3, [4, 5, [6]]], 7, 8]));
I'm trying to write a function that finds arrays that are not common to both nested arrays. Also note the arrays will be pre-sorted.
var array1 = [ [1, 2, 3], [2, 3, 4] [5, 6, 7] ];
var array2 = [ [1, 2, 3], [2, 3, 4] [7, 8, 9] ];
For the above two arrays the function should return [5, 6, 7] and [7, 8, 9].
So far I've got:
function arrayIntersection(array1, array2) {
return array2.filter(function(values1) {
return array2.indexOf(values1) === -1;
});
};
But it doesn't seem to be working. I'm guessing the indexOf() isn't doing a compares correctly. I'm trying to avoid using ES6 or polyfills.
You can use the built in .every() and .filter() array methods to accomplish this task.
var array1 = [ [1, 2, 3], [2, 3, 4], [5, 6, 7] ];
var array2 = [ [1, 2, 3], [2, 3, 4], [7, 8, 9] ];
function compareArrays(arr1, arr2) {
if (arr1.length !== arr2.length) {
return false;
} else {
return arr1.every(function(elem) {
return arr2.indexOf(elem) > -1;
});
}
}
function filterUnique(arr1, arr2) {
return arr1.filter(function(elem) {
return arr2.every(function(_elem) {
return !compareArrays(_elem, elem);
});
});
}
function filterIntersection(arr1, arr2) {
var uniqueToArr1 = filterUnique(arr1, arr2);
var uniqueToArr2 = filterUnique(arr2, arr1);
return [].concat(uniqueToArr1, uniqueToArr2);
}
console.log(filterIntersection(array1, array2));
First, you referenced the wrong array in your filter. To fix the comparison, you could turn the arrays to json. You will also need to run the filter against the second array and join the answers.:
var array1 = [ [1, 2, 3], [2, 3, 4], [5, 6, 7] ];
var array2 = [ [1, 2, 3], [2, 3, 4], [7, 8, 9] ];
function arrayIntersection(input1, input2) {
var input2NotInInput1 = input2.filter(function(values1) {
return input1.map(function(val) { return JSON.stringify(val); }).indexOf(JSON.stringify(values1)) === -1;
});
var input1NotInInput2 = input1.filter(function(values1) {
return input2.map(function(val) { return JSON.stringify(val); }).indexOf(JSON.stringify(values1)) === -1;
});
return input1NotInInput2 .concat( input2NotInInput1 );
};
console.log(arrayIntersection(array1, array2));
It's not a best option but it works
var ar1 = [
[1, 2, 3],
[2, 3, 4],
[5, 6, 7]
];
var ar2 = [
[1, 2, 3],
[2, 3, 4],
[7, 8, 9]
];
function arrayIntersection(array1, array2) {
return array2.filter(function(values1) {
return !array1.some(v => JSON.stringify(v) === JSON.stringify(values1));
});
};
var result = arrayIntersection(ar1, ar2);
console.log(result);
sym([1, 1, 2, 5], [2, 2, 3, 5], [3, 4, 5, 5]) should return [1, 4, 5]
The expected return is shown above. But I couldn't find why it fails this test. What kind of fix is needed to code below?
function sym(args) {
//debugger;
var arr=Array.from(arguments);
var resArr=[];
arr.forEach(function(arrVal){
var c=0;
arrVal.forEach(function(val,index){
console.log("arrVal",arrVal,"index",index,"val",val,"|",arrVal.slice(index+1-c));
if(index<arrVal.length-1 && arrVal.slice(index+1-c).indexOf(val)!==-1){
console.log("here");
arrVal.splice(index-c,1);
c++;
}
console.log("arrVal",arrVal,"index",index,"|",arrVal);
});
resArr.push(arrVal);
});
console.log(resArr);
resArr=resArr.reduce(function(acc,curr){
return acc.concat(curr.filter(function(val){
var notContains=acc.indexOf(val)==-1;
if(!notContains)
acc.splice(acc.indexOf(val),1);
return notContains;
}));
},[]);
console.log(resArr);
return resArr;
}
sym([1, 1, 2, 5], [2, 2, 3, 5], [3, 4, 5, 5]);
You could use a more concise version with filtering duplicates.
function sym(array) {
return array.reduce(function (r, a) {
return r.concat(a.filter(function (a, i, aa) {
return i === aa.indexOf(a);
})).filter(function (a, i, aa) {
return aa.indexOf(a) === aa.lastIndexOf(a);
});
}, []);
}
console.log(sym([[1, 1, 2, 5], [2, 2, 3, 5], [3, 4, 5, 5]])); // [1, 4, 5]
Use Sets. Their support should be sufficent. Extend their prototype and benefit from meaningful methods (union, intersection and difference taken from MDN):
Set.prototype.union = function(setB) {
var union = new Set(this);
for (var elem of setB) {
union.add(elem);
}
return union;
}
Set.prototype.intersection = function(setB) {
var intersection = new Set();
for (var elem of setB) {
if (this.has(elem)) {
intersection.add(elem);
}
}
return intersection;
}
Set.prototype.difference = function(setB) {
var difference = new Set(this);
for (var elem of setB) {
difference.delete(elem);
}
return difference;
}
Set.prototype.symmetricDifference = function(setB) {
return this.union(setB).difference(this.intersection(setB));
}
var set1 = new Set([1, 1, 2, 5]);
var set2 = new Set([2, 2, 3, 5]);
var set3 = new Set([3, 4, 5, 5]);
var result = set1.symmetricDifference(set2).symmetricDifference(set3);
console.log(result); // as Set
console.log([...result]); // as Array