So I know how to set the key dynamically like this:
var hashObj = {};
hashObj[someValue] = otherValue;
But I haven't seen any answer regarding map():
var list = ['a', 'b', 'c'];
var hashObject = list.map(function(someValue) {
return { someValue: 'blah' };
});
// should return: [ {'a': 'blah'}, {'b': 'blah'}, {'c': 'blah'} ];
I know I can do this in a for loop and such, but is this not possible in javascript using just map()?
You need to get someValue to be evaluated as its value. If you use object notation, it will be interpreted literally as string.
You can use a temporary object to achieve what you want:
var list = ['a', 'b', 'c'];
var hashObject = list.map(function(someValue) {
var tmp = {};
tmp[someValue] = 'blah';
return tmp;
});
I know it is really old question, but answer can be helpful for others.
As it has been already said, Array.prototype.map is used to get new array.
But if you want to get object instead of array - maybe you should think about using Array.prototype.reduce (https://developer.mozilla.org/pl/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce)?
const list = ['a', 'b', 'c'];
const hashObject = list.reduce((acc, current) => {
acc[current] = 'blah';
return acc;
}, {});
// hashObject equals: {"a":"blah","b":"blah","c":"blah"}
And if you want achieve the same result as mentioned in your question, you can use Array.prototype.map of course:
const list = ['a', 'b', 'c'];
const hashArrayOfObjects = list.map((current) => {
return {[current]: 'blah'};
});
// hashArrayOfObjects equals: [{"a":"blah"},{"b":"blah"},{"c":"blah"}]
You can check how it works on CodePen: https://codepen.io/grygork/pen/PojNrXO
Commonly the 'map()' method is used to get new array from each return value.
In your case, I recommend to use forEach().
var list = ['a','b','c'];
var hashObject = {};
list.forEach( function( key ) {
hashObject[ key ] = 'blah';
});
Or use object() of underscore.js library
var list = ['a','b','c'];
var hashObject = _.object( list ); // { a: undefined, b: undefined, c: undefined }
hashObject = _.mapObject( hashObject, function( val, key ) {
return 'blah';
});
Then again, Array.prototype.map is only used to get new 'array' not 'object'.
Related
This sounds like a simple task, but I can't quite figure it out: I have an array :
var array = ['opt1','sub1','subsub1','subsubsub1']
From that I want to generate the following objects:
{
opt1:{
sub1:{
subsub1:{
subsubsub1:{}
}
}
}
}
I have a way to do it, making a string and using eval, but I'm looking to avoid that, any idea?
You could use reduce:
var array = ['opt1','sub1','subsub1','subsubsub1'];
var object = {};
array.reduce(function(o, s) { return o[s] = {}; }, object);
console.log(object);
But this was only introduced in ECMAScript 5.1, so it won't be supported in some older browsers. If you want something that will be supported by legacy browsers, you could use the polyfill technique described in the MDN article above, or a simple for-loop, like this:
var array = ['opt1','sub1','subsub1','subsubsub1'];
var object = {}, o = object;
for(var i = 0; i < array.length; i++) {
o = o[array[i]] = {};
}
console.log(object);
You can use reduceRight to transform the array into a 'chain' of objects:
const array = ['a', 'b', 'c'];
const object = array.reduceRight((obj, next) => ({[next]: obj}), {});
// Example:
console.log(object); // {"a":{"b":{"c":{}}}}
you could use lodash set function
_.set(yourObject, 'a.b.c')
You can use the following Function
function arr2nestedObject(myArray){
var cp_myArray = myArray;
var lastobj = {};
while(cp_myArray.length>0){
newobj = {};
var prop = cp_myArray.pop();
newobj[prop] = lastobj;
lastobj = newobj;
}
return lastobj;
}
The following code:
var myArray = ["personal-information", "address", "street",'Great-Success'];
console.log(JSON.stringify(arr2nestedObject(myArray),undefined,2));
Would Produce the Following Output:
{
"personal-information": {
"address": {
"street": {
"Great-Success": {}
}
}
}
}
Please let me know if that was what you meant.
Kind Regards.
As #p.s.w.g answer is a very good answer with pure js, but if you want an alternative with in a descriptive and functional way of that and set a value for final nested prop, you can use ramdajs assocPath https://ramdajs.com/docs/#assocPath like below:
var array = ['opt1','sub1','subsub1','subsubsub1'];
R.assocPath(array, "the value", {});
more details:
Makes a shallow clone of an object, setting or overriding the nodes
required to create the given path, and placing the specific value at
the tail end of that path. Note that this copies and flattens
prototype properties onto the new object as well. All non-primitive
properties are copied by reference.
examples:
R.assocPath(['a', 'b', 'c'], 42, {a: {b: {c: 0}}}); //=> {a: {b: {c: 42}}}
// Any missing or non-object keys in path will be overridden
R.assocPath(['a', 'b', 'c'], 42, {a: 5}); //=> {a: {b: {c: 42}}}
I want to convert an array of objects to object with key value pairs in javascript.
var arr=[{"name1":"value1"},{"name2":"value2"},...}];
How can i convert it to an object such as
{"name1":"value1","name2":"value2",...}
I want it to be supported in majority of browsers.
You could use Object.assign and a spread syntax ... for creating a single object with the given array with objects.
var array = [{ name1: "value1" }, { name2: "value2" }],
object = Object.assign({}, ...array);
console.log(object);
You could run a reduce over the array and return a new object. But it is important to remember that if properties are the same they will be overwritten.
const newObject = array.reduce((current, next) => {
return { ...current, ...next};
}, {})
If you are using es5 and not es6:
var newObject = array.reduce(function(current, next){
return Object.assign({}, current, next);
}, {})
With modern JS (YMMV):
Split each object into entries
Aggregate all entries into one object
const arr = [{name1:"value1"}, {name2:"value2"}, {a:1,b:2}];
const obj = Object.fromEntries(arr.flatMap(Object.entries));
console.log(obj);
Try this simple logic
var arr=[{"name1":"value1"},{"name2":"value2"}];
var obj = {}; //create the empty output object
arr.forEach( function(item){
var key = Object.keys(item)[0]; //take the first key from every object in the array
obj[ key ] = item [ key ]; //assign the key and value to output obj
});
console.log( obj );
use with Array#forEach and Object.keys
var arr = [{"name1": "value1"},{"name2": "value2"}];
var obj = {};
arr.map(k => Object.keys(k).forEach(a => obj[a] = k[a]))
console.log(obj)
Using for...in loop :
var arr=[{"name1":"value1"},{"name2":"value2"}];
var obj = {};
for (var i in arr) {
obj[Object.keys(arr[i])] = arr[i][Object.keys(arr[i])];
}
console.log(obj);
Using Array.map() method with ES6 :
var arr=[{"name1":"value1"},{"name2":"value2"}];
var obj = {};
arr.map(item => obj[Object.keys(item)] = item[Object.keys(item)]);
console.log(obj);
Using Object.assign() method with ES6 spreaqd(...) assignment :
let arr=[{"name1":"value1"},{"name2":"value2"}];
let obj = Object.assign({}, ...arr);
console.log(obj);
I am looking for a short and efficient way to filter objects by key, I have this kind of data-structure:
{"Key1":[obj1,obj2,obj3], "Key2":[obj4,obj5,obj6]}
Now I want to filter by keys, for example by "Key1":
{"Key1":[obj1,obj2,obj3]}
var object = {"Key1":[1,2,3], "Key2":[4,5,6]};
var key1 = object["Key1"];
console.log(key1);
you can use the .filter js function for filter values inside an object
var keys = {"Key1":[obj1,obj2,obj3], "Key2":[obj4,obj5,obj6]};
var objectToFind;
var keyToSearch = keys.filter(function(objects) {
return objects === objectToFind
});
The keyToSearch is an array with all the objects filter by the objectToFind variable.
Remember, in the line return objects === objectToFind is where you have to should your statement. I hope it can help you.
You can create a new object based on some custom filter criteria by using a combination of Object.keys and the array .reduce method. Note this only works in es6:
var myObject = {"Key1":["a","b","c"], "Key2":["e","f","g"]}
function filterObjectByKey(obj, filterFunc) {
return Object.keys(obj).reduce((newObj, key) => {
if (filterFunc(key)) {
newObj[key] = obj[key];
}
return newObj;
}, {});
}
const filteredObj = filterObjectByKey(myObject, x => x === "Key1")
console.log(filteredObj)
Not sure what exactly are you trying to achieve, but if you want to have a set of keys that you would like to get the data for, you have quite a few options, one is:
var keys = ['alpha', 'bravo'];
var objectToFilterOn = {
alpha: 'a',
bravo: 'b',
charlie: 'c'
};
keys.forEach(function(key) {
console.log(objectToFilterOn[key]);
});
Given an object of form listed below, what is best way to obtain keys that contain a particular value? For example in following structure, if we want all the objects that possess property1, we should get object1 and object2 as answer.
Or can this be stored in a specific type of data structure for quick retrieval?
Looping over values of all objects in one approach. I am looking for something faster than that. Would appreciate suggestions.
{
object1: [property1, property2, property3],
object2: [property1],
object3: [property2]
}
If you want a faster data structure for that purpose, then you could turn your object into an ES6 map, like this:
// Sample object:
var obj = {
key1: [1, 2, 3],
key2: [1],
key3: [2]
};
// Turn into map keyed by values
var m = Object.keys(obj).reduce( (m, key) =>
obj[key].reduce( (m, v) => m.set(v, (m.get(v) || []).concat(key)), m ),
new Map
);
// Example use of the map:
console.log('1 occurs in: ', m.get(1));
Try something like this
x = {
object1: ['property1', 'property2', 'property3'],
object2: ['property1'],
object3: ['property2']
}
z = Object.keys(x).filter(function(y) {
return x[y].indexOf('property1') !== -1
})
console.log(z)
This just loops, and filters each key in your object and then does an equality check on the array of values. Kinda
var l = [];
var dict = {...}
for (var key in dict) {
var obj = dict[key];
if (obj.indexOf("property1") != -1) {
l.push(obj);
}
}
l // Here is the result
Just use the filter() function over Object.keys(data) and check if each object contains the value. You can also map() the keys to the value itself if that's what you want.
const data = {
a: [1,2,3],
b: [1],
c: [2]
};
const searchValue = 1;
const keysWithValue = Object.keys(data).filter(key => data[key].includes(searchValue));
const objectsWithValue = keysWithValue.map(key => data[key]);
console.log(keysWithValue, objectsWithValue);
Loop through your array and test each time using this:
if(Obj.hasOwnProperty("<property name>")){
array.push(obj);
}
return array;
Check this code, i think, it will help you:
const list = {
object1: ['a', 'b', 'c'],
object2: ['a'],
object3: ['c']
}
function getData(list, value){
return Object.keys(list).filter( item => list[item].indexOf(value) !== -1)
}
getData(list, 'a');
I have two arrays:
var a = ['a', 'as', 'sa'];
var b = ['sa', 'a', 'as'];
Is there anything special in shouldJS to test if these two arrays have same items? Anything Like
should(a).be.xyz(b)
that can test them? Here, xyz is what I am looking for.
A naive, but possibly sufficient solution would be to sort the arrays before comparing them:
should(a.sort()).be.eql(b.sort())
Note that sort() works in-place, mutating the original arrays.
You could implement this with should's Assertion.add feature. For example:
var a = ['a', 'as', 'sa'];
var b = ['sa', 'a', 'as'];
should.Assertion.add('haveSameItems', function(other) {
this.params = { operator: 'to be have same items' };
this.obj.forEach(item => {
//both arrays should at least contain the same items
other.should.containEql(item);
});
// both arrays need to have the same number of items
this.obj.length.should.be.equal(other.length);
});
//passes
a.should.haveSameItems(b);
b.push('d');
// now it fails
a.should.haveSameItems(b);
Slightly improved version of Michael's code:
should.Assertion.add("haveSameItems", function (other) {
this.params = { operator: "to be have same items" };
const a = this.obj.slice(0);
const b = other.slice(0);
function deepSort(objA, objB) {
const a = JSON.stringify(objA);
const b = JSON.stringify(objB);
return (a < b ? -1 : (a > b ? 1 : 0));
}
a.sort(deepSort);
b.sort(deepSort);
a.should.be.deepEqual(b);
});