how to loop over array of objects and get values - javascript

Please read fully. Do not mark it duplicate until you really find it. I have an array of objects like below.
const filterParams = [
{ 'waterfront_type[]': 'Cove' },
{ 'area[]': 'Applehead Island' },
{ 'waterfront_type[]': 'Channel' },
{ 'waterfront_type[]': 'Open Water' },
{ baths: '0 - 14' },
{ price: '0.00 - 9,876,100.00' }
];
I need to loop over this and add this to form data. I'm doing like below.
filterParams.map(param => {
return formData.append(param.key, param.value);
});
Expected: param.key is waterfront_type[] and param.value is Cove. so internally it should be formData.append('waterfront_type[]', 'Cove');
Getting: both undefined. formData.append(undefined, undefined);

You can use Object.entries(), and array destructuring to get the key, and the value.
Note: the default = [] handles the case of empty objects.
filterParams.map(param => {
const [[key, value] = []] = Object.entries(param);
return formData.append(key, value);
});
If you just need to call formData(key, value), and you don't care about the returned values (if any), use Array.forEach() instead of Array.map():
filterParams.forEach(param => {
const [[key, value] = []] = Object.entries(param);
formData.append(key, value);
});

param variable passed to .map function is a javascript object and you cannot access its keys by using just object.key. Instead do:
filterParams.map(param => {
var keys = Object.keys(param);
return formData.append(keys[0], param[keys[0]]);
});
Here, we are getting all the keys of the param object and get the first (0th index) as the key you require (assuming that your array have objects with one key).

So you want to put all dictionary entrySet into a FormData:
filterParams.forEach(param => {
Object.keys(param).forEach(function(key) {
let value = param[key];
formData.append(key, value);
});
});
It will produce the output of:
["waterfront_type%5B%5D=Cove",
"area%5B%5D=Applehead%20Island",
"waterfront_type%5B%5D=Channel",
"waterfront_type%5B%5D=Open%20Water",
"baths=0%20-%2014",
"price=0.00%20-%209%2C876%2C100.00"]

you can use javascript filters
filterParams = filterParams.filter(function(itm){
Object.keys(itm).forEach(function(key, value){
return formData.append(key, value);
})
})

Related

How do I write a Map to a text file in JavaScript? [duplicate]

I'd like to start using ES6 Map instead of JS objects but I'm being held back because I can't figure out how to JSON.stringify() a Map. My keys are guaranteed to be strings and my values will always be listed. Do I really have to write a wrapper method to serialize?
Both JSON.stringify and JSON.parse support a second argument. replacer and reviver respectively. With replacer and reviver below it's possible to add support for native Map object, including deeply nested values
function replacer(key, value) {
if(value instanceof Map) {
return {
dataType: 'Map',
value: Array.from(value.entries()), // or with spread: value: [...value]
};
} else {
return value;
}
}
function reviver(key, value) {
if(typeof value === 'object' && value !== null) {
if (value.dataType === 'Map') {
return new Map(value.value);
}
}
return value;
}
Usage:
const originalValue = new Map([['a', 1]]);
const str = JSON.stringify(originalValue, replacer);
const newValue = JSON.parse(str, reviver);
console.log(originalValue, newValue);
Deep nesting with combination of Arrays, Objects and Maps
const originalValue = [
new Map([['a', {
b: {
c: new Map([['d', 'text']])
}
}]])
];
const str = JSON.stringify(originalValue, replacer);
const newValue = JSON.parse(str, reviver);
console.log(originalValue, newValue);
You can't directly stringify the Map instance as it doesn't have any properties, but you can convert it to an array of tuples:
jsonText = JSON.stringify(Array.from(map.entries()));
For the reverse, use
map = new Map(JSON.parse(jsonText));
You can't.
The keys of a map can be anything, including objects. But JSON syntax only allows strings as keys. So it's impossible in a general case.
My keys are guaranteed to be strings and my values will always be lists
In this case, you can use a plain object. It will have these advantages:
It will be able to be stringified to JSON.
It will work on older browsers.
It might be faster.
While there is no method provided by ecmascript yet, this can still be done using JSON.stingify if you map the Map to a JavaScript primitive. Here is the sample Map we'll use.
const map = new Map();
map.set('foo', 'bar');
map.set('baz', 'quz');
Going to an JavaScript Object
You can convert to JavaScript Object literal with the following helper function.
const mapToObj = m => {
return Array.from(m).reduce((obj, [key, value]) => {
obj[key] = value;
return obj;
}, {});
};
JSON.stringify(mapToObj(map)); // '{"foo":"bar","baz":"quz"}'
Going to a JavaScript Array of Objects
The helper function for this one would be even more compact
const mapToAoO = m => {
return Array.from(m).map( ([k,v]) => {return {[k]:v}} );
};
JSON.stringify(mapToAoO(map)); // '[{"foo":"bar"},{"baz":"quz"}]'
Going to Array of Arrays
This is even easier, you can just use
JSON.stringify( Array.from(map) ); // '[["foo","bar"],["baz","quz"]]'
Using spread sytax Map can be serialized in one line:
JSON.stringify([...new Map()]);
and deserialize it with:
let map = new Map(JSON.parse(map));
Given your example is a simple use case in which keys are going to be simple types, I think this is the easiest way to JSON stringify a Map.
JSON.stringify(Object.fromEntries(map));
The way I think about the underlying data structure of a Map is as an array of key-value pairs (as arrays themselves). So, something like this:
const myMap = new Map([
["key1", "value1"],
["key2", "value2"],
["key3", "value3"]
]);
Because that underlying data structure is what we find in Object.entries, we can utilize the native JavaScript method of Object.fromEntries() on a Map as we would on an Array:
Object.fromEntries(myMap);
/*
{
key1: "value1",
key2: "value2",
key3: "value3"
}
*/
And then all you're left with is using JSON.stringify() on the result of that.
A Better Solution
// somewhere...
class Klass extends Map {
toJSON() {
var object = { };
for (let [key, value] of this) object[key] = value;
return object;
}
}
// somewhere else...
import { Klass as Map } from '#core/utilities/ds/map'; // <--wherever "somewhere" is
var map = new Map();
map.set('a', 1);
map.set('b', { datum: true });
map.set('c', [ 1,2,3 ]);
map.set( 'd', new Map([ ['e', true] ]) );
var json = JSON.stringify(map, null, '\t');
console.log('>', json);
Output
> {
"a": 1,
"b": {
"datum": true
},
"c": [
1,
2,
3
],
"d": {
"e": true
}
}
Hope that is less cringey than the answers above.
Stringify a Map instance (objects as keys are OK):
JSON.stringify([...map])
or
JSON.stringify(Array.from(map))
or
JSON.stringify(Array.from(map.entries()))
output format:
// [["key1","value1"],["key2","value2"]]
Below solution works even if you have nested Maps
function stringifyMap(myMap) {
function selfIterator(map) {
return Array.from(map).reduce((acc, [key, value]) => {
if (value instanceof Map) {
acc[key] = selfIterator(value);
} else {
acc[key] = value;
}
return acc;
}, {})
}
const res = selfIterator(myMap)
return JSON.stringify(res);
}
The very simple way.
const map = new Map();
map.set('Key1', "Value1");
map.set('Key2', "Value2");
console.log(Object.fromEntries(map));
`
Output:-
{"Key1": "Value1","Key2": "Value2"}
Just want to share my version for both Map and Set JSON.stringify only.
I'm sorting them, useful for debugging...
function replacer(key, value) {
if (value instanceof Map) {
const reducer = (obj, mapKey) => {
obj[mapKey] = value.get(mapKey);
return obj;
};
return [...value.keys()].sort().reduce(reducer, {});
} else if (value instanceof Set) {
return [...value].sort();
}
return value;
}
Usage:
const map = new Map();
const numbers= new Set()
numbers.add(3);
numbers.add(2);
numbers.add(3);
numbers.add(1);
const chars= new Set()
chars.add('b')
chars.add('a')
chars.add('a')
map.set("numbers",numbers)
map.set("chars",chars)
console.log(JSON.stringify(map, replacer, 2));
Result:
{
"chars": [
"a",
"b"
],
"numbers": [
1,
2,
3
]
}
You cannot call JSON.stringify on Map or Set.
You will need to convert:
the Map into a primitive Object, using Object.fromEntries, or
the Set into a primitive Array, using the spread operator [...]
…before calling JSON.stringify
Map
const
obj = { 'Key1': 'Value1', 'Key2': 'Value2' },
map = new Map(Object.entries(obj));
map.set('Key3', 'Value3'); // Add a new entry
// Does NOT show the key-value pairs
console.log('Map:', JSON.stringify(map));
// Shows the key-value pairs
console.log(JSON.stringify(Object.fromEntries(map), null, 2));
.as-console-wrapper { top: 0; max-height: 100% !important; }
Set
const
arr = ['Value1', 'Value2'],
set = new Set(arr);
set.add('Value3'); // Add a new item
// Does NOT show the values
console.log('Set:', JSON.stringify(set));
// Show the values
console.log(JSON.stringify([...set], null, 2));
.as-console-wrapper { top: 0; max-height: 100% !important; }
toJSON method
If you want to call JSON.stringify on a class object, you will need to override the toJSON method to return your instance data.
class Cat {
constructor(options = {}) {
this.name = options.name ?? '';
this.age = options.age ?? 0;
}
toString() {
return `[Cat name="${this.name}", age="${this.age}"]`
}
toJSON() {
return { name: this.name, age: this.age };
}
static fromObject(obj) {
const { name, age } = obj ?? {};
return new Cat({ name, age });
}
}
/*
* JSON Set adds the missing methods:
* - toJSON
* - toString
*/
class JSONSet extends Set {
constructor(values) {
super(values)
}
toString() {
return super
.toString()
.replace(']', ` ${[...this].map(v => v.toString())
.join(', ')}]`);
}
toJSON() {
return [...this];
}
}
const cats = new JSONSet([
Cat.fromObject({ name: 'Furball', age: 2 }),
Cat.fromObject({ name: 'Artemis', age: 5 })
]);
console.log(cats.toString());
console.log(JSON.stringify(cats, null, 2));
.as-console-wrapper { top: 0; max-height: 100% !important; }
Correctly round-tripping serialization
Just copy this and use it. Or use the npm package.
const serialize = (value) => JSON.stringify(value, stringifyReplacer);
const deserialize = (text) => JSON.parse(text, parseReviver);
// License: CC0
function stringifyReplacer(key, value) {
if (typeof value === "object" && value !== null) {
if (value instanceof Map) {
return {
_meta: { type: "map" },
value: Array.from(value.entries()),
};
} else if (value instanceof Set) { // bonus feature!
return {
_meta: { type: "set" },
value: Array.from(value.values()),
};
} else if ("_meta" in value) {
// Escape "_meta" properties
return {
...value,
_meta: {
type: "escaped-meta",
value: value["_meta"],
},
};
}
}
return value;
}
function parseReviver(key, value) {
if (typeof value === "object" && value !== null) {
if ("_meta" in value) {
if (value._meta.type === "map") {
return new Map(value.value);
} else if (value._meta.type === "set") {
return new Set(value.value);
} else if (value._meta.type === "escaped-meta") {
// Un-escape the "_meta" property
return {
...value,
_meta: value._meta.value,
};
} else {
console.warn("Unexpected meta", value._meta);
}
}
}
return value;
}
Why is this hard?
It should be possible to input any kind of data, get valid JSON, and from there correctly reconstruct the input.
This means dealing with
Maps that have objects as keys new Map([ [{cat:1}, "value"] ]). This means that any answer which uses Object.fromEntries is probably wrong.
Maps that have nested maps new Map([ ["key", new Map([ ["nested key", "nested value"] ])] ]). A lot of answers sidestep this by only answering the question and not dealing with anything beyond that.
Mixing objects and maps {"key": new Map([ ["nested key", "nested value"] ]) }.
and on top of those difficulties, the serialisation format must be unambiguous. Otherwise one cannot always reconstruct the input. The top answer has one failing test case, see below.
Hence, I wrote this improved version. It uses _meta instead of dataType, to make conflicts rarer and if a conflict does happen, it actually unambiguously handles it. Hopefully the code is also simple enough to easily be extended to handle other containers.
My answer does, however, not attempt to handle exceedingly cursed cases, such as a map with object properties.
A test case for my answer, which demonstrates a few edge cases
const originalValue = [
new Map([['a', {
b: {
_meta: { __meta: "cat" },
c: new Map([['d', 'text']])
}
}]]),
{ _meta: { type: "map" }}
];
console.log(originalValue);
let text = JSON.stringify(originalValue, stringifyReplacer);
console.log(text);
console.log(JSON.parse(text, parseReviver));
Accepted answer not round-tripping
The accepted answer is really lovely. However, it does not round trip when an object with a dataType property is passed it it.
// Test case for the accepted answer
const originalValue = { dataType: "Map" };
const str = JSON.stringify(originalValue, replacer);
const newValue = JSON.parse(str, reviver);
console.log(originalValue, str, newValue);
// > Object { dataType: "Map" } , Map(0)
// Notice how the input was changed into something different
I really don't know why there are so many long awesers here. This short version solved my problem:
const data = new Map()
data.set('visible', true)
data.set('child', new Map())
data.get('child').set('visible', false)
const str = JSON.stringify(data, (_, v) => v instanceof Map ? Object.fromEntries(v) : v)
// '{"visible":true,"child":{"visible":false}}'
const recovered = JSON.parse(str, (_, v) => typeof v === 'object' ? new Map(Object.entries(v)) : v)
// Map(2) { 'visible' => true, 'child' => Map(1) { 'visible' => false } }
The following method will convert a Map to a JSON string:
public static getJSONObj(): string {
return JSON.stringify(Object.fromEntries(map));
}
Example:
const x = new Map();
x.set("SomeBool", true);
x.set("number1", 1);
x.set("anObj", { name: "joe", age: 22, isAlive: true });
const json = getJSONObj(x);
// Output:
// '{"SomeBool":true,"number1":1,"anObj":{"name":"joe","age":222,"isAlive":true}}'
Although there would be some scenarios where if you were the creator of the map you would write your code in a separate 'src' file and save a copy as a .txt file and, if written concisely enough, could easily be read in, deciphered, and added to server-side.
The new file would then be saved as a .js and a reference to it sent back from the server. The file would then reconstruct itself perfectly once read back in as JS. The beauty being that no hacky iterating or parsing is required for reconstruction.

How to use map to insert key-value pair in google appScript in this unique case? [duplicate]

I'd like to start using ES6 Map instead of JS objects but I'm being held back because I can't figure out how to JSON.stringify() a Map. My keys are guaranteed to be strings and my values will always be listed. Do I really have to write a wrapper method to serialize?
Both JSON.stringify and JSON.parse support a second argument. replacer and reviver respectively. With replacer and reviver below it's possible to add support for native Map object, including deeply nested values
function replacer(key, value) {
if(value instanceof Map) {
return {
dataType: 'Map',
value: Array.from(value.entries()), // or with spread: value: [...value]
};
} else {
return value;
}
}
function reviver(key, value) {
if(typeof value === 'object' && value !== null) {
if (value.dataType === 'Map') {
return new Map(value.value);
}
}
return value;
}
Usage:
const originalValue = new Map([['a', 1]]);
const str = JSON.stringify(originalValue, replacer);
const newValue = JSON.parse(str, reviver);
console.log(originalValue, newValue);
Deep nesting with combination of Arrays, Objects and Maps
const originalValue = [
new Map([['a', {
b: {
c: new Map([['d', 'text']])
}
}]])
];
const str = JSON.stringify(originalValue, replacer);
const newValue = JSON.parse(str, reviver);
console.log(originalValue, newValue);
You can't directly stringify the Map instance as it doesn't have any properties, but you can convert it to an array of tuples:
jsonText = JSON.stringify(Array.from(map.entries()));
For the reverse, use
map = new Map(JSON.parse(jsonText));
You can't.
The keys of a map can be anything, including objects. But JSON syntax only allows strings as keys. So it's impossible in a general case.
My keys are guaranteed to be strings and my values will always be lists
In this case, you can use a plain object. It will have these advantages:
It will be able to be stringified to JSON.
It will work on older browsers.
It might be faster.
While there is no method provided by ecmascript yet, this can still be done using JSON.stingify if you map the Map to a JavaScript primitive. Here is the sample Map we'll use.
const map = new Map();
map.set('foo', 'bar');
map.set('baz', 'quz');
Going to an JavaScript Object
You can convert to JavaScript Object literal with the following helper function.
const mapToObj = m => {
return Array.from(m).reduce((obj, [key, value]) => {
obj[key] = value;
return obj;
}, {});
};
JSON.stringify(mapToObj(map)); // '{"foo":"bar","baz":"quz"}'
Going to a JavaScript Array of Objects
The helper function for this one would be even more compact
const mapToAoO = m => {
return Array.from(m).map( ([k,v]) => {return {[k]:v}} );
};
JSON.stringify(mapToAoO(map)); // '[{"foo":"bar"},{"baz":"quz"}]'
Going to Array of Arrays
This is even easier, you can just use
JSON.stringify( Array.from(map) ); // '[["foo","bar"],["baz","quz"]]'
Using spread sytax Map can be serialized in one line:
JSON.stringify([...new Map()]);
and deserialize it with:
let map = new Map(JSON.parse(map));
Given your example is a simple use case in which keys are going to be simple types, I think this is the easiest way to JSON stringify a Map.
JSON.stringify(Object.fromEntries(map));
The way I think about the underlying data structure of a Map is as an array of key-value pairs (as arrays themselves). So, something like this:
const myMap = new Map([
["key1", "value1"],
["key2", "value2"],
["key3", "value3"]
]);
Because that underlying data structure is what we find in Object.entries, we can utilize the native JavaScript method of Object.fromEntries() on a Map as we would on an Array:
Object.fromEntries(myMap);
/*
{
key1: "value1",
key2: "value2",
key3: "value3"
}
*/
And then all you're left with is using JSON.stringify() on the result of that.
A Better Solution
// somewhere...
class Klass extends Map {
toJSON() {
var object = { };
for (let [key, value] of this) object[key] = value;
return object;
}
}
// somewhere else...
import { Klass as Map } from '#core/utilities/ds/map'; // <--wherever "somewhere" is
var map = new Map();
map.set('a', 1);
map.set('b', { datum: true });
map.set('c', [ 1,2,3 ]);
map.set( 'd', new Map([ ['e', true] ]) );
var json = JSON.stringify(map, null, '\t');
console.log('>', json);
Output
> {
"a": 1,
"b": {
"datum": true
},
"c": [
1,
2,
3
],
"d": {
"e": true
}
}
Hope that is less cringey than the answers above.
Stringify a Map instance (objects as keys are OK):
JSON.stringify([...map])
or
JSON.stringify(Array.from(map))
or
JSON.stringify(Array.from(map.entries()))
output format:
// [["key1","value1"],["key2","value2"]]
Below solution works even if you have nested Maps
function stringifyMap(myMap) {
function selfIterator(map) {
return Array.from(map).reduce((acc, [key, value]) => {
if (value instanceof Map) {
acc[key] = selfIterator(value);
} else {
acc[key] = value;
}
return acc;
}, {})
}
const res = selfIterator(myMap)
return JSON.stringify(res);
}
The very simple way.
const map = new Map();
map.set('Key1', "Value1");
map.set('Key2', "Value2");
console.log(Object.fromEntries(map));
`
Output:-
{"Key1": "Value1","Key2": "Value2"}
Just want to share my version for both Map and Set JSON.stringify only.
I'm sorting them, useful for debugging...
function replacer(key, value) {
if (value instanceof Map) {
const reducer = (obj, mapKey) => {
obj[mapKey] = value.get(mapKey);
return obj;
};
return [...value.keys()].sort().reduce(reducer, {});
} else if (value instanceof Set) {
return [...value].sort();
}
return value;
}
Usage:
const map = new Map();
const numbers= new Set()
numbers.add(3);
numbers.add(2);
numbers.add(3);
numbers.add(1);
const chars= new Set()
chars.add('b')
chars.add('a')
chars.add('a')
map.set("numbers",numbers)
map.set("chars",chars)
console.log(JSON.stringify(map, replacer, 2));
Result:
{
"chars": [
"a",
"b"
],
"numbers": [
1,
2,
3
]
}
You cannot call JSON.stringify on Map or Set.
You will need to convert:
the Map into a primitive Object, using Object.fromEntries, or
the Set into a primitive Array, using the spread operator [...]
…before calling JSON.stringify
Map
const
obj = { 'Key1': 'Value1', 'Key2': 'Value2' },
map = new Map(Object.entries(obj));
map.set('Key3', 'Value3'); // Add a new entry
// Does NOT show the key-value pairs
console.log('Map:', JSON.stringify(map));
// Shows the key-value pairs
console.log(JSON.stringify(Object.fromEntries(map), null, 2));
.as-console-wrapper { top: 0; max-height: 100% !important; }
Set
const
arr = ['Value1', 'Value2'],
set = new Set(arr);
set.add('Value3'); // Add a new item
// Does NOT show the values
console.log('Set:', JSON.stringify(set));
// Show the values
console.log(JSON.stringify([...set], null, 2));
.as-console-wrapper { top: 0; max-height: 100% !important; }
toJSON method
If you want to call JSON.stringify on a class object, you will need to override the toJSON method to return your instance data.
class Cat {
constructor(options = {}) {
this.name = options.name ?? '';
this.age = options.age ?? 0;
}
toString() {
return `[Cat name="${this.name}", age="${this.age}"]`
}
toJSON() {
return { name: this.name, age: this.age };
}
static fromObject(obj) {
const { name, age } = obj ?? {};
return new Cat({ name, age });
}
}
/*
* JSON Set adds the missing methods:
* - toJSON
* - toString
*/
class JSONSet extends Set {
constructor(values) {
super(values)
}
toString() {
return super
.toString()
.replace(']', ` ${[...this].map(v => v.toString())
.join(', ')}]`);
}
toJSON() {
return [...this];
}
}
const cats = new JSONSet([
Cat.fromObject({ name: 'Furball', age: 2 }),
Cat.fromObject({ name: 'Artemis', age: 5 })
]);
console.log(cats.toString());
console.log(JSON.stringify(cats, null, 2));
.as-console-wrapper { top: 0; max-height: 100% !important; }
Correctly round-tripping serialization
Just copy this and use it. Or use the npm package.
const serialize = (value) => JSON.stringify(value, stringifyReplacer);
const deserialize = (text) => JSON.parse(text, parseReviver);
// License: CC0
function stringifyReplacer(key, value) {
if (typeof value === "object" && value !== null) {
if (value instanceof Map) {
return {
_meta: { type: "map" },
value: Array.from(value.entries()),
};
} else if (value instanceof Set) { // bonus feature!
return {
_meta: { type: "set" },
value: Array.from(value.values()),
};
} else if ("_meta" in value) {
// Escape "_meta" properties
return {
...value,
_meta: {
type: "escaped-meta",
value: value["_meta"],
},
};
}
}
return value;
}
function parseReviver(key, value) {
if (typeof value === "object" && value !== null) {
if ("_meta" in value) {
if (value._meta.type === "map") {
return new Map(value.value);
} else if (value._meta.type === "set") {
return new Set(value.value);
} else if (value._meta.type === "escaped-meta") {
// Un-escape the "_meta" property
return {
...value,
_meta: value._meta.value,
};
} else {
console.warn("Unexpected meta", value._meta);
}
}
}
return value;
}
Why is this hard?
It should be possible to input any kind of data, get valid JSON, and from there correctly reconstruct the input.
This means dealing with
Maps that have objects as keys new Map([ [{cat:1}, "value"] ]). This means that any answer which uses Object.fromEntries is probably wrong.
Maps that have nested maps new Map([ ["key", new Map([ ["nested key", "nested value"] ])] ]). A lot of answers sidestep this by only answering the question and not dealing with anything beyond that.
Mixing objects and maps {"key": new Map([ ["nested key", "nested value"] ]) }.
and on top of those difficulties, the serialisation format must be unambiguous. Otherwise one cannot always reconstruct the input. The top answer has one failing test case, see below.
Hence, I wrote this improved version. It uses _meta instead of dataType, to make conflicts rarer and if a conflict does happen, it actually unambiguously handles it. Hopefully the code is also simple enough to easily be extended to handle other containers.
My answer does, however, not attempt to handle exceedingly cursed cases, such as a map with object properties.
A test case for my answer, which demonstrates a few edge cases
const originalValue = [
new Map([['a', {
b: {
_meta: { __meta: "cat" },
c: new Map([['d', 'text']])
}
}]]),
{ _meta: { type: "map" }}
];
console.log(originalValue);
let text = JSON.stringify(originalValue, stringifyReplacer);
console.log(text);
console.log(JSON.parse(text, parseReviver));
Accepted answer not round-tripping
The accepted answer is really lovely. However, it does not round trip when an object with a dataType property is passed it it.
// Test case for the accepted answer
const originalValue = { dataType: "Map" };
const str = JSON.stringify(originalValue, replacer);
const newValue = JSON.parse(str, reviver);
console.log(originalValue, str, newValue);
// > Object { dataType: "Map" } , Map(0)
// Notice how the input was changed into something different
I really don't know why there are so many long awesers here. This short version solved my problem:
const data = new Map()
data.set('visible', true)
data.set('child', new Map())
data.get('child').set('visible', false)
const str = JSON.stringify(data, (_, v) => v instanceof Map ? Object.fromEntries(v) : v)
// '{"visible":true,"child":{"visible":false}}'
const recovered = JSON.parse(str, (_, v) => typeof v === 'object' ? new Map(Object.entries(v)) : v)
// Map(2) { 'visible' => true, 'child' => Map(1) { 'visible' => false } }
The following method will convert a Map to a JSON string:
public static getJSONObj(): string {
return JSON.stringify(Object.fromEntries(map));
}
Example:
const x = new Map();
x.set("SomeBool", true);
x.set("number1", 1);
x.set("anObj", { name: "joe", age: 22, isAlive: true });
const json = getJSONObj(x);
// Output:
// '{"SomeBool":true,"number1":1,"anObj":{"name":"joe","age":222,"isAlive":true}}'
Although there would be some scenarios where if you were the creator of the map you would write your code in a separate 'src' file and save a copy as a .txt file and, if written concisely enough, could easily be read in, deciphered, and added to server-side.
The new file would then be saved as a .js and a reference to it sent back from the server. The file would then reconstruct itself perfectly once read back in as JS. The beauty being that no hacky iterating or parsing is required for reconstruction.

JavaScript: How to get all object values of an object without iterator

I convert multidimensional array to object and when I try to return the converted object, I get only the first row values.
Here is my code.
const price = [
[
[1642636800000, 6.479682086929113],
[1642723200000, 6.34357451008912],
[1642809600000, 5.121543485810777],
[1642896000000, 3.9740756848518095],
[1642982400000, 4.3575187509716],
[1643068800000, 3.9012325159931027],
[1643155200000, 3.4317289914580345],
[1643241600000, 3.2757454409610474],
[1643328000000, 2.638504600238906],
[1643414400000, 2.7780564535948247],
[1643500800000, 2.6434238272520734],
[1643587200000, 2.4336766397631195],
[1643673600000, 2.3564650737278945],
[1643760000000, 2.0999935033955395],
[1643846400000, 2.030984947088804],
[1643932800000, 1.9601855774194021],
[1644019200000, 1.939260102893443],
[1644105600000, 1.9099357711674574],
[1644192000000, 1.756137354391081],
[1644278400000, 1.5997203967365643],
[1644364800000, 1.5123161188548575],
[1644451200000, 1.519374648506311],
[1644537600000, 1.537046985055748],
[1644624000000, 1.508372954955599],
[1644710400000, 1.55420714318404],
[1644796800000, 1.5875532111414001],
[1644883200000, 1.6653755421073082],
[1644969600000, 1.6647861014789664],
[1645056000000, 1.7214785428910968],
[1645142400000, 1.7801924052482303],
[1645177320000, 1.7624504335296196],
],
];
code to convert price array to JSON object
const prices = price.map(function (value, key) {
return {
first: value[0][1],
second: value[0][1],
};
});
console.log(prices); //prints only the first rows
How can I get all rows of the object?
Thanks
the problem here is that you have three dimensional array so when you map over it, it will only map over the elements inside first array to do what you want you can try this
price.map(function (item) {
return item.map(function (item) {
return { first: item[0], second: item[1] };
});
})
:)
const prices = price[0].map(function(value, key) {
return {
first: value[0],
second: value[1],
};
});
const pricesArr = [
[
[1642636800000, 6.479682086929113],
[1642723200000, 6.34357451008912],
[1642809600000, 5.121543485810777],
[1642896000000, 3.9740756848518095],
[1642982400000, 4.3575187509716],
[1643068800000, 3.9012325159931027],
[1643155200000, 3.4317289914580345],
[1643241600000, 3.2757454409610474],
[1643328000000, 2.638504600238906],
[1643414400000, 2.7780564535948247],
[1643500800000, 2.6434238272520734],
[1643587200000, 2.4336766397631195],
[1643673600000, 2.3564650737278945],
[1643760000000, 2.0999935033955395],
[1643846400000, 2.030984947088804],
[1643932800000, 1.9601855774194021],
[1644019200000, 1.939260102893443],
[1644105600000, 1.9099357711674574],
[1644192000000, 1.756137354391081],
[1644278400000, 1.5997203967365643],
[1644364800000, 1.5123161188548575],
[1644451200000, 1.519374648506311],
[1644537600000, 1.537046985055748],
[1644624000000, 1.508372954955599],
[1644710400000, 1.55420714318404],
[1644796800000, 1.5875532111414001],
[1644883200000, 1.6653755421073082],
[1644969600000, 1.6647861014789664],
[1645056000000, 1.7214785428910968],
[1645142400000, 1.7801924052482303],
[1645177320000, 1.7624504335296196],
],
];
const prices = pricesArr.flat(1).map(price => ({
first: price[0],
second: price[1]
}));
console.log(prices);
You have a nested array, you can flatten it first and then, iterate to create an array of object.

How to convert an array to an object?

I have some data that comes like an array, i will show you it looks
Vm.table=[{
Name:"amina";
},
{
Prenom:"adfe";
},
{
Region:"rabat";
}];
To an object like
Vm.obj={
Name:"amina",
Prenom:"adfe",
Region:"rabat"
};
I need to set a code that may convert the table to this object, i put a lot of functions but is not working to me if someone can help.
You can use Object.assign() and spread operator
const table=[{Name:"amina"},{Prenom:"adfe"},{Region:"rabat"}];
const result = Object.assign({}, ...table);
console.log(result);
You can use reduce
Vm.obj = Vm.table.reduce((obj, col) => {
Object.keys(col).forEach(k => obj[k] = col[k])
return obj;
}, {});
Of course, if you have repeating keys, this will take the last key/val pair available.
Use Array.prototype.reduce and I am assuning objects have only single key, value pair.
let array =[{
Name:"amina"
},
{
Prenom:"adfe"
},
{
Region:"rabat"
}];
let obj = array.reduce((prev, curr) => {
const key = Object.keys(curr)[0];
prev[key] = curr[key];
return prev;
}, {});
console.log(obj);

Adding keys to a json using an array of string

I have a basic json question that is giving me headache since a couple of hours, I am trying to dynamically add keys to a Json object using an array of string.
Here is my array of string:
let key = ['session', 'view_state', 'footer', 'config', 'items']
I have another variable which is jsonValue and is my whole json object. I want to end up with one of those options:
jsonValue.session.view_state.footer.config.items
jsonValue['session']['view_state']['footer']['config']['items']
This is my best attempt using a forEach.
forEach(jsonKeys, (el) => {
jsonCollection += jsonCollection !== undefined ? '."' +[el + '"'] : [ '"' + el + '"' ];
})
But I have this result: 
undefined"session"."view_state"."footer"."config"."items"
Any help will be appreciated!
To get a value using the keys array
Iterate with Array#reduce, check the type of the current value, if it's an object, return the value of the key, if not return undefined:
const obj = {
"demo": true,
"session": {
"view_state": {
"footer": {
"config": {
"items": [
1,
2
]
}
}
}
}
};
const keys = ['session', 'view_state', 'footer', 'config', 'items'];
const value = keys.reduce((val, key) => val && typeof val === 'object' ?
val[key] : undefind, obj);
console.log(value);
To add a value using the keys array
Use Array#reduceRight to create a chain of objects with the value you want. Use Object#assign to update the original object with the results:
const keys = ['session', 'view_state', 'footer', 'config', 'items'];
const obj = { demo: true };
Object.assign(obj, keys.reduceRight((val, key) => ({ [key]: val }), [1, 2])); // replace [1, 2] with the actual items
console.log(obj);

Categories

Resources