Assuming this JSON object:
var obj = {
"set1": [1, 2, 3],
"set2": [4, 5, 6, 7, 8],
"set3": [9, 10, 11, 12]
};
The "set2" property may be retrieved like so:
obj["set2"]
Is there a way to retrieve the "set2" property by index? It is the second property of the JSON object. This does not work (of course):
obj[1]
So, let's say that I want to retrieve the second property of the JSON object, but I don't know its name - how would I do it then?
Update: Yes, I understand that objects are collections of unordered properties. But I don't think that the browsers mess with the "original" order defined by the JSON literal / string.
Objects in JavaScript are collections of unordered properties. Objects are hashtables.
If you want your properties to be in alphabetical order, one possible solution would be to create an index for your properties in a separate array. Just a few hours ago, I answered a question on Stack Overflow which you may want to check out:
Iterating over a JavaScript object in sort order based on particular key value of a child object
Here's a quick adaptation for your object1:
var obj = {
"set1": [1, 2, 3],
"set2": [4, 5, 6, 7, 8],
"set3": [9, 10, 11, 12]
};
var index = [];
// build the index
for (var x in obj) {
index.push(x);
}
// sort the index
index.sort(function (a, b) {
return a == b ? 0 : (a > b ? 1 : -1);
});
Then you would be able to do the following:
console.log(obj[index[1]]);
The answer I cited earlier proposes a reusable solution to iterate over such an object. That is unless you can change your JSON to as #Jacob Relkin suggested in the other answer, which could be easier.
1 You may want to use the hasOwnProperty() method to ensure that the properties belong to your object and are not inherited from Object.prototype.
I know this is an old question but I found a way to get the fields by index.
You can do it by using the Object.keys method.
When you call the Object.keys method it returns the keys in the order they were assigned (See the example below). I tested the method below in the following browsers:
Google Chrome version 43.0
Firefox version 33.1
Internet Explorer version 11
I also wrote a small extension to the object class so you can call the nth key of the object using getByIndex.
// Function to get the nth key from the object
Object.prototype.getByIndex = function(index) {
return this[Object.keys(this)[index]];
};
var obj1 = {
"set1": [1, 2, 3],
"set2": [4, 5, 6, 7, 8],
"set3": [9, 10, 11, 12]
};
var obj2 = {
"set2": [4, 5, 6, 7, 8],
"set1": [1, 2, 3],
"set3": [9, 10, 11, 12]
};
log('-- Obj1 --');
log(obj1);
log(Object.keys(obj1));
log(obj1.getByIndex(0));
log('-- Obj2 --');
log(obj2);
log(Object.keys(obj2));
log(obj2.getByIndex(0));
// Log function to make the snippet possible
function log(x) {
var d = document.createElement("div");
if (typeof x === "object") {
x = JSON.stringify(x, null, 4);
}
d.textContent= x;
document.body.appendChild(d);
}
No, there is no way to access the element by index in JavaScript objects.
One solution to this if you have access to the source of this JSON, would be to change each element to a JSON object and stick the key inside of that object like this:
var obj = [
{"key":"set1", "data":[1, 2, 3]},
{"key":"set2", "data":[4, 5, 6, 7, 8]},
{"key":"set3", "data":[9, 10, 11, 12]}
];
You would then be able to access the elements numerically:
for(var i = 0; i < obj.length; i++) {
var k = obj[i]['key'];
var data = obj[i]['data'];
//do something with k or data...
}
Simple solution, just one line..
var obj = {
"set1": [1, 2, 3],
"set2": [4, 5, 6, 7, 8],
"set3": [9, 10, 11, 12]
};
obj = Object.values(obj);
obj[1]....
Here you can access "set2" property following:
var obj = {
"set1": [1, 2, 3],
"set2": [4, 5, 6, 7, 8],
"set3": [9, 10, 11, 12]
};
var output = Object.keys(obj)[1];
Object.keys return all the keys of provided object as Array..
Jeroen Vervaeke's answer is modular and the works fine, but it can cause problems if it is using with jQuery or other libraries that count on "object-as-hashtables" feature of Javascript.
I modified it a little to make usable with these libs.
function getByIndex(obj, index) {
return obj[Object.keys(obj)[index]];
}
You could iterate over the object and assign properties to indexes, like this:
var lookup = [];
var i = 0;
for (var name in obj) {
if (obj.hasOwnProperty(name)) {
lookup[i] = obj[name];
i++;
}
}
lookup[2] ...
However, as the others have said, the keys are in principle unordered. If you have code which depends on the corder, consider it a hack. Make sure you have unit tests so that you will know when it breaks.
"""
This could be done in python as follows.
Form the command as a string and then execute
"""
context = {
"whoami": "abc",
"status": "0",
"curStep": 2,
"parentStepStatus": {
"step1":[{"stepStatus": 0, "stepLog": "f1.log"}],
"step2":[{"stepStatus": 0, "stepLog": "f2.log"}]
}
}
def punc():
i = 1
while (i < 10):
x = "print(" + "context" + "['parentStepStatus']" + "['%s']"%("step%s")%(i) + ")"
exec(x)
i+=1
punc()
There is no "second property" -- when you say var obj = { ... }, the properties inside the braces are unordered. Even a 'for' loop walking through them might return them in different orders on different JavaScript implementations.
it is quite simple...
var obj = {
"set1": [1, 2, 3],
"set2": [4, 5, 6, 7, 8],
"set3": [9, 10, 11, 12]
};
jQuery.each(obj, function(i, val) {
console.log(i); // "set1"
console.log(val); // [1, 2, 3]
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
var obj = {
"set1": [
1,
2,
3
],
"set2": [
4,
5,
6,
7,
8
],
"set3": [
9,
10,
11,
12
]
};
var outputKeys = Object.keys(obj)[1];
var outputValues = Object.values(obj)[1];
//outputKeys would be "set2"`enter code here`
//outPutValues would be [4,5,6,7,8]
My solution:
Object.prototype.__index=function(index)
{var i=-1;
for (var key in this)
{if (this.hasOwnProperty(key) && typeof(this[key])!=='function')
{++i;
}
if (i>=index)
{return this[key];
}
}
return null;
}
aObj={'jack':3, 'peter':4, '5':'col', 'kk':function(){alert('hell');}, 'till':'ding'};
alert(aObj.__index(4));
Related
I am learning Javascript on a book and have to practice reversing an array by creating my own reverse function. The array must be reversed without creating a new variable to hold the reversed array. I thought I found a solution, but when I try to output my answer in 2 different ways (see below), I get different outputs:
function reverseArrayInPlace(array) {
for (var i = 0; i < array.length; i += 1) {
array = array.slice(0, i).concat(array.pop()).concat(array.slice(i));
}
console.log(array);
}
var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
Here are the outputs:
reverseArrayInPlace(array);
console.log(array);
> [ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 ]
> [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
When console.log() is used within the function, I get my desired answer.
When console.log() is used outside the function, I get the original array with the last element missing. I would like an explanation to this phenomenon.
The array in the function is on a different scope than that at the global / window level -- the global array is never touched; the function changes a local copy of it instead.
If you didn't pass array as a parameter to the function, then it would act on the now unmasked global array variable:
function reverseArrayInPlace() { // <-- no parameter
for (var i = 0; i < array.length; i += 1) {
array = array.slice(0, i).concat(array.pop()).concat(array.slice(i));
}
console.log(array);
}
var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
reverseArrayInPlace();
console.log(array);
(...although it is generally bad practice to use globals like that, partly because it's easy to accidentally mask them with local variables just as you did here. A better pattern would be for functions to receive their data as params and return a value, so you can decide, when you call the function, what to assign that returned value to.)
Inside reverseArrayInPlace you are reassigning the array variable, not changing (mutating) it. The array you pass in, therefore, is not changed. The inside console.log sees the new array while the one outside sees the original.
Perhaps you want something like this instead
function reverseArrayInPlace(array) {
for (var i = 0; i < array.length; i += 1) {
array = array.slice(0, i).concat(array.pop()).concat(array.slice(i));
}
return array;
}
var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var newArray = reverseArrayInPlace(array)
console.log(newArray)
Just a different approach by using the function stack for storing an item of the array by popping the value, check the length of the array and call the function again with the same object reference and then unshift the temporary stored value.
While working for a small amount of values and because of the limited stack, it is not advisable to use this beside of educational purpose.
function reverseArrayInPlace(array) {
var temp = array.pop();
if (array.length) {
reverseArrayInPlace(array);
}
array.unshift(temp);
}
var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
reverseArrayInPlace(array);
console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }
In the first loop of your for you are calling array.pop() which modifies the array passed as argument, but then you are creating a new array storing it in the same variable, so the reference to the original array is lost, and then in the subsequent loops the modified array is the one being generated inside your function.
Look at this code, I added a line to copy the original array, thus not modificating the original passed as argument.
function reverseArrayInPlace(array) {
array = array.slice(); //copying the passed array to not change the original
for (var i = 0; i < array.length; i += 1) {
array = array.slice(0, i).concat(array.pop()).concat(array.slice(i));
}
console.log(array);
}
var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
reverseArrayInPlace(array);
console.log(array);
I have an object called assignments which contains arrays as such;
assignments = {
'version_1': [1,2,3,4,5],
'version_2': [6,7,8,9,0],
'version_3': [3,4,5,6,7]
}
if I want to get the values of a particular version I can simply say something like console.log(assignments.version_2);
But what if I have an integer set in a variable? How would I reference the values dynamically. e.g.
var version_id = 2;
console.log(assignments.version_[version_id]);
You can use this :
var version_id = 2;
console.log(assignments["version_" + version_id]);
Or, if you know you only have to support browsers that have es6, you can do :
assignments[`version_${version_id}`]
Es6 template strings make things nicer
Try following
var assignments = {
'version_1': [1, 2, 3, 4, 5],
'version_2': [6, 7, 8, 9, 0],
'version_3': [3, 4, 5, 6, 7]
};
var version_id = 2;
console.log(assignments["version_" + version_id]);
assignments = {
'version_1': [1,2,3,4,5],
'version_2': [6,7,8,9,0],
'version_3': [3,4,5,6,7]
}
console.log(assignments['version_2'])
I have this javascript object..
var obj = {
'02/08/2016': 2,
'03/10/2016': 4,
'04/05/2016': 2,
'04/06/2016': 35,
'04/19/2016': 4,
'04/26/2016': 22,
'05/09/2016': 15,
'05/24/2016': 2,
'05/30/2016': 4,
'07/14/2016': 7,
'08/18/2016': 200
};
// Does not work
$(obj).each(function(index,value) {
console.log(index);
console.log(value);
});
// Does not work, also what does putting it in bracket notation do here?
var labels = $.map(obj, function(index, value) {
return [index];
});
Why can I not iterate the object? I am trying to place this data in two separate arrays (like below) for chart.js
var arr1 = ['02/08/2016', '03/10/2016', '04/05/2016', ..];
var arr2 = [2, 4, 2, ...];
Code Fiddle: https://jsfiddle.net/zjgb6ez4/
The issue with your logic is, $.each() has two signatures:
$(selector).each(function(index,value) {...} // For HTML DOM selectors.
$.each(obj, function(index,value) {...} // For JavaScript Objects & Arrays.
What you have used is for jQuery selectors, DOM Iteration. This way is specifically for iterating JavaScript Objects or Arrays.
Also, since you need two arrays. You can't use each or map function for this, as they return only one array. Instead, it is better to use Object.keys and Object.values():
var obj = {
'02/08/2016': 2,
'03/10/2016': 4,
'04/05/2016': 2,
'04/06/2016': 35,
'04/19/2016': 4,
'04/26/2016': 22,
'05/09/2016': 15,
'05/24/2016': 2,
'05/30/2016': 4,
'07/14/2016': 7,
'08/18/2016': 200
};
var arr1 = Object.keys(obj);
var arr2 = Object.values(obj);
console.log(arr1);
console.log(arr2);
Note: Object.values() is an experimental technology. Because this technology's specification has not stabilised, check the compatibility table for usage in various browsers. Also note that the syntax and behaviour of an experimental technology is subject to change in future versions of browsers as the specification changes.
Without Object.values()
var obj = {
'02/08/2016': 2,
'03/10/2016': 4,
'04/05/2016': 2,
'04/06/2016': 35,
'04/19/2016': 4,
'04/26/2016': 22,
'05/09/2016': 15,
'05/24/2016': 2,
'05/30/2016': 4,
'07/14/2016': 7,
'08/18/2016': 200
};
var arr1 = Object.keys(obj);
var arr2 = arr1.map(function (v) {
return obj[v];
});
console.log(arr1);
console.log(arr2);
Using jQuery to iterate over a plain object you need to use $.each().
$.each(obj, function(index,value) {...}
A pure Javascript solution might be:
for (var index in obj) {
console.log(index);
console.log(obj[index]);
}
You can use the keys() and values() methods on Object.
var obj = {
'02/08/2016': 2,
'03/10/2016': 4,
'04/05/2016': 2,
'04/06/2016': 35,
'04/19/2016': 4,
'04/26/2016': 22,
'05/09/2016': 15,
'05/24/2016': 2,
'05/30/2016': 4,
'07/14/2016': 7,
'08/18/2016': 200
};
var arr1 = Object.keys(obj);
var arr2 = Object.values(obj);
This is plain JavaScript solution, without jQuery. But note that values() method is not supported in all browsers yet.
This question already has answers here:
Merge/flatten an array of arrays
(84 answers)
Closed 6 years ago.
Below is my array if items that I want to reduce it to a single list of arrays..
var input=[
[
2
],
[
3,
13
],
[
4,
14
],
[
5,
15,
25,
35
]
]
var output=[
2,
3,
13,
4,
14,
5,
15,
25,
35
]
My code:
function reduceArray(item){
for(var i=0;i<item.length;i++){
return i;
}
}
var result=result.map((item)=>{
if(item.length>0){
return reduceArray(item);
}else{
return item;
}
})
which produces the same result.Can anyone please figure out where I'm doing wrong or any other approach to achieve this..Thanks
input.reduce(function(a, x) { return a.concat(x); });
// => [2, 3, 13, 4, 14, 5, 15, 25, 35]
reduce sets the accumulator to the first element (or a starting value if provided), then calls the function with the accumulator and each successive element. The function we provide is concatenation. If we say input is [a, b, c], then the above command will be equivalent to a.concat(b).concat(c). [concat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat) produces a new array by smushing two or more arrays together.
EDIT: Actually, there is another possible answer:
Array.prototype.concat.apply(input[0], array.slice(1));
// => [2, 3, 13, 4, 14, 5, 15, 25, 35]
This directly calls concat with multiple arguments; if input is again [a, b, c], then this is equivalent to a.concat(b, c). apply calls a function with a given receiver and arguments; slice will give us just a part of the array, in this case everything starting from the first element (which we need to chop off since it needs to be the receiver of the concat call).
One liner would be
input = [[2],[3,13],[4,14],[5,15,25,35]];
[].concat.apply([],input);
You can use lodash's flattenDeep()
_.flattenDeep([1, [2, [3, [4]], 5]]);
// → [1, 2, 3, 4, 5]
User concat.check this for more information http://www.w3schools.com/jsref/jsref_concat_array.asp
var input=[[2],[3,13],[4,14],[5,15,25,35]];
var output=[];
for(var i = 0; i < input.length; i++)
{
output = output.concat(input[i]);
}
console.log(output);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
use concat is the perfect way
The concat() method is used to join two or more arrays.
This method does not change the existing arrays, but returns a new array, containing the values of the joined arrays.
var newArr = [];
for(var i = 0; i < input.length; i++)
{
newArr = newArr.concat(input[i]);
}
console.log(newArr);
I'm retrieving some data and the data looks like this:
1, 2, 3, 4, 5
6, 7, 8, 9, 10
11, 12, 13, 14, 15
I want it to look like this
[
[[1],[2],[3],[4],[5]],
[[6],[7],[8],[9],[10]],
[[11],[12],[13],[14],[15]]
]
So that I may address the array like a matrix, data[0][1] would be "2".
Through this answer, it's almost there, but not quite. I'm having trouble getting to look like what I want.
How about this, assuming this accurately represents your input data:
var data = "1,2,3,4,5\n6,7,8,9,10\n11,12,13,14,15";
var matrix = data.split('\n').map(function(val) {
return val.split(',');
});
Note that your specified output is probably not what you meant. Each number should probably not be its own single-item array. Instead, the code above produces:
[
[1, 2, 3, 4, 5],
[6, 7, 8, 9, 10],
[11, 12, 13, 14, 1]
]
Which means matrix[0][1] would return 2, as opposed to having to do matrix[0][1][0]
Edit: As noted in the comments, I've left it up to you to ensure this fits your browser-support needs. This also goes for every other line of JS you ever write...
NOTE - If you need to iterate through an array use a simple for, and not a for..in
for..in returns the items in no guaranteed order which is probably not what you want when working with an array
for..in returns not the just the array elements, but anything added to the Array prototype (meaning if you use a traditional for loop you can be completely confident the code will work regardless of what external libraries may be included on the page. No need to worry that some other coder has added properties/methods to Array.prototype)
If \n is the line separator and , is the item seperator within a line, you can use something like:
/* assuming data is already filled like:
1,2,3,4,5
6,7,8,9,10
11,12,13,14,15
*/
var arr = data.split("\n"), arr2 = [];
for(var i = 0; i < arr.length; i++) {
if(arr[i] != '') arr2.push(arr[i].split(','));
}
console.log(arr2);
/* arr2 will be like:
[
[1, 2, 3, 4, 5],
[6, 7, 8, 9, 10],
[11, 12, 13, 14, 15]
]
*/
var data = '1,2,3,4,5,6,7,8,9,10,11,12,13,14,15'.split(',');
var matrixData = [];
while (data.length > 0) {
matrixData.push(data.splice(0, 5));
}
document.write(matrixData[0][1]);
Edit: If you get the data as a simple array of numbers