key:[id,name,address]
value:[7,John,NewYork]
I wish to create a json data like{"id": 7, "name": "John", "address": "NewYork"} using for(...){...},
and then return it to ajax
$.ajax({
//what kind of format should json data be here?
data:??json data??,
dataType: 'json',
});
Please help me
To the first part of your question:
You could use Array#forEach() and assign all properties with the correspondet value.
var key = ['id', 'name', 'address'],
value = [7, 'John', 'New York'],
object = {};
key.forEach(function (k, i) {
object[k] = value[i];
})
document.write('<pre>' + JSON.stringify(object, 0, 4) + '</pre>');
You could:
iterate through both arrays...
...add the 1st array element to an empty obj as a key...
...and assign the 2nd array element to the 1st array element as it's value.
Each iteration will be paired as key/value when stringified as a JSON.
I'm surprised it actually worked, take a look at the demo below:
SNIPPET
var x = ['id', 'name', 'address'];
var y = [7, 'John', 'NewYork'];
function arrMerge(k, v) {
var obj = {};
for (var i = 0; i < k.length; i++) {
obj[k[i]] = v[i];
}
return obj;
}
var z = arrMerge(x, y);
var json = JSON.stringify(z);
console.log(json);
You can write a general function that zips two arrays together into an object if they're of equal length (also assuming they're in the correct order).
function zip(arr1, arr2) {
if (arr1.length !== arr2.length) return false;
const obj = {};
for (let i = 0; i < arr1.length; i++) {
const key = arr1[i];
obj[key] = arr2[i];
}
return obj;
}
zip(arr1, arr2); // { id: 7, name: "John", address: "NewYork" }
DEMO
You can then use that object as the value of data in your AJAX process.
data
Type: PlainObject or String or Array
Data to be sent to the server. It is converted to a query string, if not already a string.
jQuery documentation
I guess unlike forEach, since it returns the result, Array.prototype.reduce() comes very handy for these operations. You can even use it at the stage of declaring your JSON data (jData here).
var key = ['id', 'name', 'address'],
value = [7, 'John', 'New York'],
jData = JSON.stringify(key.reduce((p,c,i) => {p[c] = value[i]; return p},{}));
document.write("<pre>" + jData + "</pre>");
I need to loop through array and each array in array that has extra values, push them to their parent array as separate item. I hope this makes sense..
This is the structure of my initial array:
{type:
[ 0:
value: "tomato"
],
[ 1:
{value: "apple",
[ extras:
[ 0: { value: "green" } ],
[ 1: { value: "red" } ]
]
],
[ 2:
value: "pineapple"
]
}
What the result would have to look like:
[type:
[ 0:
tomato
],
[ 1:
apple,
green,
red
],
[ 2:
pineapple
]
]
What I've tried and failed: (I also commented the error I get on right line)
var response = /* json of first codeblock in question is response from ajax */;
var items = JSON.parse( response );
var type = Object.keys( items )[0];
var myArray = []
var count = items[type].lenght;
//Loop through main items in "type"
for( i = 0; i < count; i++ ) {
var value = items[type][i][value];
myArray[type][i] = [value]; //Uncaught TypeError: Cannot set property '0' of undefined
if( items[type][i][extras] ) {
var extracount = items[type][i][extras].lenght;
//Loop through extras
for( k = 0; k < extracount; k++ ) {
var extra = items[type][i][extras][k][value];
myArray[type][i].push( extra );
}
}
}
My main problem that I don't understand and that seems to be the problem in my example as well:
If I declare an empty array, how do I:
push an item to that array also declaring a new array around that item?
push another item to that array that was made around the first item?
This is what I believe you want. The following code may be incorrect, because I'm approximating what I believe your items object contains.
var items = {
type: [
{
value: "tomato"
},
{
value: "apple",
extras: [
{
value: "green"
}, {
value: "red"
}
]
},
{
value: "pineapple"
}
]
};
var myArray = {
type: []
};
var count = items['type'].length;
//Loop through main items in "type"
for (i = 0; i < count; i++) {
var subarray = [];
subarray.push(items['type'][i]['value']);
if (items['type'][i]['extras']) {
var extracount = items['type'][i]['extras'].length;
//Loop through extras
for (k = 0; k < extracount; k++) {
var extra = items['type'][i]['extras'][k]['value'];
subarray.push(extra);
}
}
myArray['type'].push(subarray);
}
Some notes:
You will definitely need to learn the difference between an array and an object in javascript. There are plenty of resources online for this.
When retrieving/manipulating a property prop from an object obj (i.e. for a key-value pair), you will need to use obj.prop or obj['prop']. Note the use of a string in the latter example.
For an array arr, you should use arr.push(value) to push a new value onto the array.
Your problem is here:
var value = items[type][i][value];
you should change it to
var value = items[type][i].value;
How can I convert something like initialArray array of JSON objects into finalObject map?
var initialArray = [
{ id:'id1', name:'name1' },
{ id:'id2', name:'name2' },
{ id:'id3', name:'name3' },
{ id:'id4', name:'name4' }
];
var finalObject = {
'id1':'name1',
'id2':'name2',
'id3':'name3',
'id4':'name4'
}
Things to consider:
IDs are strings.
I tried for in loop - couldn't make it to work - http://jsfiddle.net/5af9R/23/
Any ideas?
You need to operate on the objects in your array, not strings containing their indexes in the array.
You should also use a regular for loop to iterate over an array.
Your JSFiddle, fixed:
var x = [ {id:'1', img:'img1'}, {id:'2', img:'img2'}, {id:'3', img:'img3'} ];
var resp = {};
for( var i = 0 ; i < x.length ; i++ ){
var obj = x[i];
resp[obj.id] = obj.img;
}
document.write( JSON.stringify(resp, undefined, 2) );
DEMO
You can loop over the array, and for each object, add a new property to finalObject whose property name is the id, and whose value is the name.
var finalObject = {};
for (var i = 0, max = initialArray.length; i < max; i++)
finalObject[initialArray[i].id] = initialArray[i].name;
resp[key.id] = key.img;
You correctly call it key. But you need a value;
resp[x[key].id] = x[key].img;
var finalObject = initialArray.reduce(function(ret, obj){
ret[obj.id] = obj.name;
return ret;
}, {});
This solution is specific to the property names for the specific question, but Array.prototype.reduce is a function I use all the time for any sort of array iteration that requires a non-array result.
You're not using For In correctly jsFiddle
var x = [ {id:'1', img:'img1'}, {id:'2', img:'img2'}, {id:'3', img:'img3'} ];
var resp = {};
for( var key in x ){
resp['id' + x[key].id] = x[key].img;
}
document.write( JSON.stringify(resp, undefined, 2) );
for (var i=0; i<x.length; i++) {
var id = 'id' + x[i].id;
var img = x[i].img;
resp[id] = img;
}
if i have understood correctly you can do something like
var x =' [ {"id":"1", "img":"img1"}, {"id":"2", "img":"img2"}, {"id":"3", "img":"img3"}]';
var resp = {};
var json = $.parseJSON(x);
$(json).each(function(i,v){
resp[v.id]=v.img;
});
console.log( resp);
DEMO
you talked about json but in the fiddle you provided there was no json even jquery was not added as a resource so i made some assumptions
Today I was on the same question and I didn't find an answer here, except the answer of #adam-rackis.
The way I found is :
var initialArray = [
{ id:'id1', name:'name1' },
{ id:'id2', name:'name2' },
{ id:'id3', name:'name3' },
{ id:'id4', name:'name4' }
],
finalObject = {};
$.each(initialArray, function(k,v) {
finalObject[v.name] = v.value;
});
I need to store some statistics using JavaScript in a way like I'd do it in C#:
Dictionary<string, int> statistics;
statistics["Foo"] = 10;
statistics["Goo"] = statistics["Goo"] + 1;
statistics.Add("Zoo", 1);
Is there an Hashtable or something like Dictionary<TKey, TValue> in JavaScript?
How could I store values in such a way?
Use JavaScript objects as associative arrays.
Associative Array: In simple words associative arrays use Strings instead of Integer numbers as index.
Create an object with
var dictionary = {};
JavaScript allows you to add properties to objects by using the following syntax:
Object.yourProperty = value;
An alternate syntax for the same is:
Object["yourProperty"] = value;
If you can, also create key-to-value object maps with the following syntax:
var point = { x:3, y:2 };
point["x"] // returns 3
point.y // returns 2
You can iterate through an associative array using the for..in loop construct as follows
for(var key in Object.keys(dict)){
var value = dict[key];
/* use key/value for intended purpose */
}
var associativeArray = {};
associativeArray["one"] = "First";
associativeArray["two"] = "Second";
associativeArray["three"] = "Third";
If you are coming from an object-oriented language you should check this article.
All modern browsers support a JavaScript Map object. There are a couple of reasons that make using a Map better than Object:
An Object has a prototype, so there are default keys in the map.
The keys of an Object are Strings, where they can be any value for a Map.
You can get the size of a Map easily while you have to keep track of size for an Object.
Example:
var myMap = new Map();
var keyObj = {},
keyFunc = function () {},
keyString = "a string";
myMap.set(keyString, "value associated with 'a string'");
myMap.set(keyObj, "value associated with keyObj");
myMap.set(keyFunc, "value associated with keyFunc");
myMap.size; // 3
myMap.get(keyString); // "value associated with 'a string'"
myMap.get(keyObj); // "value associated with keyObj"
myMap.get(keyFunc); // "value associated with keyFunc"
If you want keys that are not referenced from other objects to be garbage collected, consider using a WeakMap instead of a Map.
Unless you have a specific reason not to, just use a normal object. Object properties in JavaScript can be referenced using hashtable-style syntax:
var hashtable = {};
hashtable.foo = "bar";
hashtable['bar'] = "foo";
Both foo and bar elements can now then be referenced as:
hashtable['foo'];
hashtable['bar'];
// Or
hashtable.foo;
hashtable.bar;
Of course this does mean your keys have to be strings. If they're not strings they are converted internally to strings, so it may still work. Your mileage may vary.
Since every object in JavaScript behaves like - and is generally implemented as - a hashtable, I just go with that...
var hashSweetHashTable = {};
In C# the code looks like:
Dictionary<string,int> dictionary = new Dictionary<string,int>();
dictionary.add("sample1", 1);
dictionary.add("sample2", 2);
or
var dictionary = new Dictionary<string, int> {
{"sample1", 1},
{"sample2", 2}
};
In JavaScript:
var dictionary = {
"sample1": 1,
"sample2": 2
}
A C# dictionary object contains useful methods, like dictionary.ContainsKey()
In JavaScript, we could use the hasOwnProperty like:
if (dictionary.hasOwnProperty("sample1"))
console.log("sample1 key found and its value is"+ dictionary["sample1"]);
If you require your keys to be any object rather than just strings, then you could use my jshashtable.
Note:
Several years ago, I had implemented the following hashtable, which has had some features that were missing to the Map class. However, that's no longer the case — now, it's possible to iterate over the entries of a Map, get an array of its keys or values or both (these operations are implemented copying to a newly allocated array, though — that's a waste of memory and its time complexity will always be as slow as O(n)), remove specific items given their key, and clear the whole map.
Therefore, my hashtable implementation is only useful for compatibility purposes, in which case it'd be a saner approach to write a proper polyfill based on this.
function Hashtable() {
this._map = new Map();
this._indexes = new Map();
this._keys = [];
this._values = [];
this.put = function(key, value) {
var newKey = !this.containsKey(key);
this._map.set(key, value);
if (newKey) {
this._indexes.set(key, this.length);
this._keys.push(key);
this._values.push(value);
}
};
this.remove = function(key) {
if (!this.containsKey(key))
return;
this._map.delete(key);
var index = this._indexes.get(key);
this._indexes.delete(key);
this._keys.splice(index, 1);
this._values.splice(index, 1);
};
this.indexOfKey = function(key) {
return this._indexes.get(key);
};
this.indexOfValue = function(value) {
return this._values.indexOf(value) != -1;
};
this.get = function(key) {
return this._map.get(key);
};
this.entryAt = function(index) {
var item = {};
Object.defineProperty(item, "key", {
value: this.keys[index],
writable: false
});
Object.defineProperty(item, "value", {
value: this.values[index],
writable: false
});
return item;
};
this.clear = function() {
var length = this.length;
for (var i = 0; i < length; i++) {
var key = this.keys[i];
this._map.delete(key);
this._indexes.delete(key);
}
this._keys.splice(0, length);
};
this.containsKey = function(key) {
return this._map.has(key);
};
this.containsValue = function(value) {
return this._values.indexOf(value) != -1;
};
this.forEach = function(iterator) {
for (var i = 0; i < this.length; i++)
iterator(this.keys[i], this.values[i], i);
};
Object.defineProperty(this, "length", {
get: function() {
return this._keys.length;
}
});
Object.defineProperty(this, "keys", {
get: function() {
return this._keys;
}
});
Object.defineProperty(this, "values", {
get: function() {
return this._values;
}
});
Object.defineProperty(this, "entries", {
get: function() {
var entries = new Array(this.length);
for (var i = 0; i < entries.length; i++)
entries[i] = this.entryAt(i);
return entries;
}
});
}
Documentation of the class Hashtable
Methods:
get(key)
Returns the value associated to the specified key.
Parameters:
key: The key from which to retrieve the value.
put(key, value)
Associates the specified value to the specified key.
Parameters:
key: The key to which associate the value.
value: The value to associate to the key.
remove(key)
Removes the specified key, together with the value associated to it.
Parameters:
key: The key to remove.
clear()
Clears the whole hashtable, by removing all its entries.
indexOfKey(key)
Returns the index of the specified key, according to the order entries have been added.
Parameters:
key: The key of which to get the index.
indexOfValue(value)
Returns the index of the specified value, according to the order entries have been added.
Parameters:
value: The value of which to get the index.
Remarks:
Values are compared by identity.
entryAt(index)
Returns an object with a key and a value properties, representing the entry at the specified index.
Parameters:
index: The index of the entry to get.
containsKey(key)
Returns whether the hashtable contains the specified key.
Parameters:
key: The key to look for.
containsValue(value)
Returns whether the hashtable contains the specified value.
Parameters:
value: The value to look for.
forEach(iterator)
Iterates through all the entries in the hashtable, calling specified iterator.
Parameters:
iterator: A method with three parameters, key, value and index, where index represents the index of the entry according to the order it's been added.
Properties:
length (Read-only)
Gets the count of the entries in the hashtable.
keys (Read-only)
Gets an array of all the keys in the hashtable.
values (Read-only)
Gets an array of all the values in the hashtable.
entries (Read-only)
Gets an array of all the entries in the hashtable. They're represented the same as the method entryAt().
function HashTable() {
this.length = 0;
this.items = new Array();
for (var i = 0; i < arguments.length; i += 2) {
if (typeof (arguments[i + 1]) != 'undefined') {
this.items[arguments[i]] = arguments[i + 1];
this.length++;
}
}
this.removeItem = function (in_key) {
var tmp_previous;
if (typeof (this.items[in_key]) != 'undefined') {
this.length--;
var tmp_previous = this.items[in_key];
delete this.items[in_key];
}
return tmp_previous;
}
this.getItem = function (in_key) {
return this.items[in_key];
}
this.setItem = function (in_key, in_value) {
var tmp_previous;
if (typeof (in_value) != 'undefined') {
if (typeof (this.items[in_key]) == 'undefined') {
this.length++;
} else {
tmp_previous = this.items[in_key];
}
this.items[in_key] = in_value;
}
return tmp_previous;
}
this.hasItem = function (in_key) {
return typeof (this.items[in_key]) != 'undefined';
}
this.clear = function () {
for (var i in this.items) {
delete this.items[i];
}
this.length = 0;
}
}
https://gist.github.com/alexhawkins/f6329420f40e5cafa0a4
var HashTable = function() {
this._storage = [];
this._count = 0;
this._limit = 8;
}
HashTable.prototype.insert = function(key, value) {
// Create an index for our storage location by passing
// it through our hashing function
var index = this.hashFunc(key, this._limit);
// Retrieve the bucket at this particular index in
// our storage, if one exists
//[[ [k,v], [k,v], [k,v] ] , [ [k,v], [k,v] ] [ [k,v] ] ]
var bucket = this._storage[index]
// Does a bucket exist or do we get undefined
// when trying to retrieve said index?
if (!bucket) {
// Create the bucket
var bucket = [];
// Insert the bucket into our hashTable
this._storage[index] = bucket;
}
var override = false;
// Now iterate through our bucket to see if there are any conflicting
// key value pairs within our bucket. If there are any, override them.
for (var i = 0; i < bucket.length; i++) {
var tuple = bucket[i];
if (tuple[0] === key) {
// Override value stored at this key
tuple[1] = value;
override = true;
}
}
if (!override) {
// Create a new tuple in our bucket.
// Note that this could either be the new empty bucket we created above
// or a bucket with other tupules with keys that are different than
// the key of the tuple we are inserting. These tupules are in the same
// bucket because their keys all equate to the same numeric index when
// passing through our hash function.
bucket.push([key, value]);
this._count++
// Now that we've added our new key/val pair to our storage
// let's check to see if we need to resize our storage
if (this._count > this._limit * 0.75) {
this.resize(this._limit * 2);
}
}
return this;
};
HashTable.prototype.remove = function(key) {
var index = this.hashFunc(key, this._limit);
var bucket = this._storage[index];
if (!bucket) {
return null;
}
// Iterate over the bucket
for (var i = 0; i < bucket.length; i++) {
var tuple = bucket[i];
// Check to see if key is inside bucket
if (tuple[0] === key) {
// If it is, get rid of this tuple
bucket.splice(i, 1);
this._count--;
if (this._count < this._limit * 0.25) {
this._resize(this._limit / 2);
}
return tuple[1];
}
}
};
HashTable.prototype.retrieve = function(key) {
var index = this.hashFunc(key, this._limit);
var bucket = this._storage[index];
if (!bucket) {
return null;
}
for (var i = 0; i < bucket.length; i++) {
var tuple = bucket[i];
if (tuple[0] === key) {
return tuple[1];
}
}
return null;
};
HashTable.prototype.hashFunc = function(str, max) {
var hash = 0;
for (var i = 0; i < str.length; i++) {
var letter = str[i];
hash = (hash << 5) + letter.charCodeAt(0);
hash = (hash & hash) % max;
}
return hash;
};
HashTable.prototype.resize = function(newLimit) {
var oldStorage = this._storage;
this._limit = newLimit;
this._count = 0;
this._storage = [];
oldStorage.forEach(function(bucket) {
if (!bucket) {
return;
}
for (var i = 0; i < bucket.length; i++) {
var tuple = bucket[i];
this.insert(tuple[0], tuple[1]);
}
}.bind(this));
};
HashTable.prototype.retrieveAll = function() {
console.log(this._storage);
//console.log(this._limit);
};
/******************************TESTS*******************************/
var hashT = new HashTable();
hashT.insert('Alex Hawkins', '510-599-1930');
//hashT.retrieve();
//[ , , , [ [ 'Alex Hawkins', '510-599-1930' ] ] ]
hashT.insert('Boo Radley', '520-589-1970');
//hashT.retrieve();
//[ , [ [ 'Boo Radley', '520-589-1970' ] ], , [ [ 'Alex Hawkins', '510-599-1930' ] ] ]
hashT.insert('Vance Carter', '120-589-1970').insert('Rick Mires', '520-589-1970').insert('Tom Bradey', '520-589-1970').insert('Biff Tanin', '520-589-1970');
//hashT.retrieveAll();
/*
[ ,
[ [ 'Boo Radley', '520-589-1970' ],
[ 'Tom Bradey', '520-589-1970' ] ],
,
[ [ 'Alex Hawkins', '510-599-1930' ],
[ 'Rick Mires', '520-589-1970' ] ],
,
,
[ [ 'Biff Tanin', '520-589-1970' ] ] ]
*/
// Override example (Phone Number Change)
//
hashT.insert('Rick Mires', '650-589-1970').insert('Tom Bradey', '818-589-1970').insert('Biff Tanin', '987-589-1970');
//hashT.retrieveAll();
/*
[ ,
[ [ 'Boo Radley', '520-589-1970' ],
[ 'Tom Bradey', '818-589-1970' ] ],
,
[ [ 'Alex Hawkins', '510-599-1930' ],
[ 'Rick Mires', '650-589-1970' ] ],
,
,
[ [ 'Biff Tanin', '987-589-1970' ] ] ]
*/
hashT.remove('Rick Mires');
hashT.remove('Tom Bradey');
//hashT.retrieveAll();
/*
[ ,
[ [ 'Boo Radley', '520-589-1970' ] ],
,
[ [ 'Alex Hawkins', '510-599-1930' ] ],
,
,
[ [ 'Biff Tanin', '987-589-1970' ] ] ]
*/
hashT.insert('Dick Mires', '650-589-1970').insert('Lam James', '818-589-1970').insert('Ricky Ticky Tavi', '987-589-1970');
hashT.retrieveAll();
/* NOTICE HOW THE HASH TABLE HAS NOW DOUBLED IN SIZE UPON REACHING 75% CAPACITY, i.e. 6/8. It is now size 16.
[,
,
[ [ 'Vance Carter', '120-589-1970' ] ],
[ [ 'Alex Hawkins', '510-599-1930' ],
[ 'Dick Mires', '650-589-1970' ],
[ 'Lam James', '818-589-1970' ] ],
,
,
,
,
,
[ [ 'Boo Radley', '520-589-1970' ],
[ 'Ricky Ticky Tavi', '987-589-1970' ] ],
,
,
,
,
[ [ 'Biff Tanin', '987-589-1970' ] ] ]
*/
console.log(hashT.retrieve('Lam James')); // 818-589-1970
console.log(hashT.retrieve('Dick Mires')); // 650-589-1970
console.log(hashT.retrieve('Ricky Ticky Tavi')); //987-589-1970
console.log(hashT.retrieve('Alex Hawkins')); // 510-599-1930
console.log(hashT.retrieve('Lebron James')); // null
You can create one using like the following:
var dictionary = { Name:"Some Programmer", Age:24, Job:"Writing Programs" };
// Iterate over using keys
for (var key in dictionary) {
console.log("Key: " + key + " , " + "Value: "+ dictionary[key]);
}
// Access a key using object notation:
console.log("Her name is: " + dictionary.Name)