Converting an Array into object in Javascript - javascript

I want to know the best way to convert an array in Js to object.
This is the sample of what i want to do.
Input => ['abc', 'def'];
Output => { abc: true, def: true }
I have done it using the code below. But just wanted to know if
**function toObject(strings) {
var rv = {}
strings.forEach(string => {
rv[string] = true
})
return rv
}**
This function serves the purpose. But any experts out there with a best and efficient way possible.

Not sure what you mean by best and efficient way possible, since yours is alright according to me, this is a less versbose version
var output = strings.reduce( (a,c) => (a[c]=true, a), {})
Demo
var strings = ['abc', 'def'];
var output = strings.reduce( (a,c) => (a[c]=true, a), {});
console.log(output);

You could map single objects and assign it to the same object.
var array = ['abc', 'def'],
object = Object.assign(...array.map(key => ({ [key]: true })));
console.log(object);

Related

how can i check if an array of objects contains a key which is in array of strings js?

We have an array of objects like
const arr = [{id: "someId", name: {...}}, ...];
const skippedKeys = ["id"...]
How can i filtered the array of object based on skipped keys?
The result should be:
const result = [{name: {...}}, ...];
Also i don't want to make a cycle inside the cycle.
the result also could be implemented using lodash library.
we should remove key with value as well.
Since you stated that it could be implemented using lodash, here is some code using lodash:
let result = _.map(arr, (el)=> _.omit(el, skippedKeys))
const result = arr.map(obj =>
Object.keys(obj).reduce(
(res, key) => (
skippedKeys.includes(key) ? res : {...res, [key]: obj[key]}
),
{},
));
It's simple and no need for any nested cycles. There are two option to do that
Using includes function
const result = arr.filter((item) => !result.includes(item.id));
Using set
const dataSet = new Set(skippedKeys);
const result = arr.filter((item) => !dataSet.has(item.id));
I prefer the second one as it excludes double checks. Hope the answer was helpful.

Create new JSON string from array

Fairly new to JSON and I'm trying to get my head around conversions. I have an array:
['Role1', 'Role2', 'Role3']
and I'm trying to stringify it so that it reads as
{"Role1": true, "Role2": true, "Role3": true}
So far I've tried assigning the original array to an object and the calling stringify but I can't figure out how to add the boolean value in the string. Thanks in advance.
You'll have to create an intermediate reduce function to assign those values before converting to JSON.
const data = ['Role1', 'Role2', 'Role3']
const makeJson = () =>
JSON.stringify(data.reduce((a, c) => ({ ...a, [c]: true }), {}))
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
Is this what you need as output?
const arr = ['Role1', 'Role2', 'Role3']
const result = JSON.stringify(arr.reduce((a, n)=>{
return {
...a,
[n]: new Boolean(true).toString()
}
},{}))
console.log(result)
Another approach could be to combine Object.fromEntries with Array.prototype.map
const data = ['Role1', 'Role2', 'Role3']
const result = Object.fromEntries(data.map(s => [s, true]));
console.log(JSON.stringify(result));
This should do the trick:
let rolesArray = ['Role1', 'Role2', 'Role3'];
let rolesObject = {};
// iterate over roles to fill an object
rolesArray.forEach((role) => {
rolesObject[role] = true;
});
JSON.stringify(rolesObject) // Outputs the desired string
Or in a more concise way but less readable for a SO example :
JSON.stringify(rolesArray.reduce((o, s) => { o[s] = true; return o }, {}));
I have a preference for using the for-loop — still valid but other methods will be much short.
var array = ["Role1", "Role2", "Role3"],
json = {};
for (i = 0; i < array.length; i++) {
json[array[i]] = true;
}
console.log(json);
Use reduce() so we can set the value to true without a second loop
Using the spread operator (...) to merge the objects
const data = ['Role1', 'Role2', 'Role3'];
const obj = data.reduce((prev, cur) => ({ ...prev, [cur]: true }), {});
console.log(obj);
console.log(JSON.stringify(obj));
{
"Role1": true,
"Role2": true,
"Role3": true
}
{"Role1":true,"Role2":true,"Role3":true}
if you want to do that you must use code Below .
json-encode(Array)

Transform from string array to hashmap in Lodash

What is the most precise way to transform from this
["access","edit","delete"]
to this
{access:true, edit:true, update:true}
Currently i loop to assign each value in object but i wonder if lodash already provide function for this
Use reduce(). This can all be done with a simple one-liner, that doesn't require any libraries:
const input = ["access","edit","delete"];
console.log(
input.reduce((obj, key) => { obj[key] = true; return obj; }, {})
);
With the new es6 spread syntax, you can even make this easier:
const input = ["access","edit","delete"];
console.log(
input.reduce((obj, key) => ({...obj, [key]: true}), {})
);
LODASH
You can map it to a array of entries and then simply use fromPairs of lodash
_.fromPairs(input.map(k=>[k, true]))
var input = ["access","edit","delete"];
var res = _.fromPairs(input.map(k=>[k,true]));
console.log(res);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
ES6
You can map your input to a key (your each input) value (true) pair of objects and assign them.
Object.assign( ...input.map(k=>({[k]: true})))
var input = ["access","edit","delete"]
var res = Object.assign( ...input.map(k=>({[k]: true})));
console.log(res);
In case you want a Map object you can map your input to entries (as used in lodash example) and simply construct a new Map like
new Map(input.map(k=>[k, true]))
No need to import a library for something so simple, just reduce the array of keys into an object indexed by those keys:
const input = ["access","edit","delete"];
const output = input.reduce((a, key) => Object.assign(a, {[key]: true}), {});
console.log(output);
Or, assigning to the property of the accumulator rather than using Object.assign:
const input = ["access","edit","delete"];
const output = input.reduce((a, key) => {
a[key] = true;
return a;
}, {});
console.log(output);
If you absolutely want to use lodash (As opposed to the above vanilla javascript reduce() answers), you can use _.mapValues() to accomplish this:
const input = ["access","edit","delete"];
const output = _.mapValues(_.keyBy(input), () => true)
console.log(output);
<script src="https://cdn.jsdelivr.net/npm/lodash#4.17.11/lodash.min.js" integrity="sha256-7/yoZS3548fXSRXqc/xYzjsmuW3sFKzuvOCHd06Pmps=" crossorigin="anonymous"></script>

Converting a String to Multiple objects (javascript)

I have the following string: Jack:13,Phil:15,Lucy:12I'm trying to fetch objects from this string.
This string would have 3 people objects with their ages. How can this be achieved?
I've tried the following:
var s = 'Jack:13,Phil:15,Lucy:12'
var obj1 = eval("("+s+")");
var obj2 = JSON.parse(s);
Logging any of the obj variables returns errors. Am I missing a simple trick here? Any explanation would be appreciated, thanks.
In general, if you're doing replaces on a string to turn it into something you can pass eval or JSON.parse, that's probably not your best approach. An in particular, avoid using eval (or its cousin new Function) when you can (you certainly can here), and always avoid eval (or its cousin new Function) with untrusted input.
A pair of splits with map does it:
const s = 'Jack:13,Phil:15,Lucy:12'
const people = s.split(",")
.map(e => e.split(":"))
.map(([name, age]) => ({name, age}));
console.log(people);
...or in ES5:
var s = 'Jack:13,Phil:15,Lucy:12'
var people = s.split(",")
.map(function(e) { return e.split(":"); })
.map(function(e) { return {name: e[0], age: e[1]}; });
console.log(people);
I'm not sure why I did two maps rather than just doing the second split and creating the object in the same callback; I guess I'm thinking more and more in a "functional programming" way. I'd change it, but Eddie's answer already does it in a single map, so...
...(edit) but since it looks like you wanted separate properties rather than using the person's name like Eddie did, here's an example of the above but with just a single map:
const s = 'Jack:13,Phil:15,Lucy:12'
const people = s.split(",")
.map(e => {
const [name, age] = e.split(":");
return {name, age};
});
console.log(people);
...or in ES5:
var s = 'Jack:13,Phil:15,Lucy:12'
var people = s.split(",")
.map(function(e) {
var parts = e.split(":");
return {name: parts[0], age: parts[1]};
});
console.log(people);
You can split() the string and use map() to loop thru the array. This will return an array of objects.
var s = 'Jack:13,Phil:15,Lucy:12';
var result = s.split(',').map(o => {
let [k, v] = o.split(':');
return {[k]: v};
});
console.log(result);
If you want a single object, you can use reduce
var s = 'Jack:13,Phil:15,Lucy:12';
var result = s.split(',').reduce((c, o) => {
let [k, v] = o.split(':');
return Object.assign(c, {[k]: v});
}, {});
console.log(result);
You can try with:
const result = s.split(',')
.map(value => value.split(':'))
.reduce((acc, [name, value]) => {
acc[name] = +value;
return acc;
}, {});
Output:
{
"Jack": 13,
"Phil": 15,
"Lucy": 12
}
As I'm sure you've worked out there are many ways to do this, I thought I'd add another method
let s = 'Jack:13,Phil:15,Lucy:12'
let obj = {};
s.split(",").forEach(part => {
obj[part.split(":")[0]] = part.split(":")[1];
})
console.log(obj);
This is a simple split the string and then on each item of the new array do a split and push the results into an empty object already declared.
You could split the parts and build a new object with key/value pairs.
var string = 'Jack:13,Phil:15,Lucy:12',
result = Object.assign(...string
.split(',')
.map(s => (([k, v]) => ({ [k]: v }))(s.split(':')))
);
console.log(result);
For getting an array with objects
var string = 'Jack:13,Phil:15,Lucy:12',
result = string
.split(',')
.map(s => (([name, age]) => ({ name, age }))(s.split(':')));
console.log(result);
Easy to do with .map():
var s = 'Jack:13,Phil:15,Lucy:12';
var items = s.split(',')
.map((entry) => entry.split(':'))
.map((item) => ({name: item[0], age: item[1]}));
console.log(items);

turning an array into an array with objects

I have been trying to figure out how to turn an array into an array with objects.
for example i have a json file to start with and the json file looks sorta like this
var data=[{"tasknumber":304030,
"date":"2012-05-05",
"operator":"john doe"},
{"tasknumber":23130,
"date":"2012-07-07",
"operator":"john doeeeeeeee"},
{"tasknumber":233330,
"date":"2012-08-08",
"operator":"john doe"}]
so i applied the _.countBy function that is within the underscore.js library and i get an object like this
{"john doe":2,"john doeeeeeeee":1}
ive been trying to figure out how to turn this into an array with objects so it would look something like this but i have failed in every attempt and i dont know were to start
[{operator:"john doe",
count: 2},
{operator: "john doeeeeeeee",
count:1}]
i have tried a few things but all i get is tragedy and everything breaks, does anyone know if there are any librarys or anything that could help with this sort of thing?
Given the object (not array) {"john doe":2,"john doeeeeeeee":1} as input you can get your desired output like this:
var input = {"john doe":2,"john doeeeeeeee":1};
var output = Object.keys(input).map(function(k) {
return {
operator: k,
count: input[k]
};
});
console.log(output);
Or with ES6 arrow function syntax:
var input = {"john doe":2,"john doeeeeeeee":1};
var output = Object.keys(input).map((k) => ({ operator: k, count: input[k] }) );
console.log(output);
(Note that Underscore probably provides an even shorter way to do this, but I'm not familiar with Underscore so I've just given a plain JS solution.)
Further reading:
Object.keys()
array .map()
=> arrow functions
Given your initial data array, you can just run this:
var data=[{"tasknumber":304030,
"date":"2012-05-05",
"operator":"john doe"},
{"tasknumber":23130,
"date":"2012-07-07",
"operator":"john doeeeeeeee"},
{"tasknumber":233330,
"date":"2012-08-08",
"operator":"john doe"}];
Function definition
const count = data => {
// get data in format like _.countBy
const o = data.map(x => x.operator).reduce((acc, cur) => { acc[cur] ? acc[cur] += 1 : acc[cur] = 1; return acc; }, {});
// transform object into array of object
return Object.keys(o).map(operator => ({operator, count: o[operator]}));
};
Test it by producing output
console.log(count(data));
Here is an untested underscore approach that takes your initial values as loaded from the JSON file and converts directly into your desired output format:
_.chain(input)
.groupBy(function(entry) { return entry.operator })
.map(function(entries, operator) {
return {
operator: operator,
count: entries.length
}
})
.value();

Categories