convert json to array/map - javascript

My rest API returns with the following json content:
[{
"key": "apple",
"value": "green"
},
{
"key": "banana",
"value": "yellow"
}]
I am iterating through the list with this code:
this.props.json.map(row => {
return <RowRender key={id.row} row={row} />
}
It works because the content is displayed but on the web browser's console I can see an error:
map is not a function
I googled for it and I changed my code to this:
Array.prototype.slice.call(this.props.json).map(row => {
return <RowRender key={id.row} row={row} />
}
It works without any error but seems so complicated. Is that the correct way to do this job?
UPDATE
What I tried:
JSON.parse(...).map: Unexpected end of JSON input
JSON.parse(JSON.stringify(...)).map(...): data is displayed but I get an error: JSON.parse(...).map is not a function
Array(...).map: Each child in array or iterator should have a unique key.

Use Object.entries() to get both the key and values, then give that to Map() to allow you to select your values by key.
let myMap = new Map(Object.entries(this.props.json));

in your code this.props.json is not an array, it's an array-like object and map is an array function. what your doing to solve this, is converting that array-like object into an array, with .slice()
a more elegant way to do this:
Array.from(this.props.json).map(row => <RowRender key={id.row} row={row} />)

let jsonMap = JSON.stringify([...map.entries()])
let myMap = new Map(JSON.parse(jsonMap));

You can do it very easily as #Gary mentioned in his answer:
From Map to JSON (string keys):
const personsJson = `{"1":{"firstName":"Jan","lastName":"Kowalski"},"2":{"firstName":"Justyna","lastName":"Kowalczyk"}}`;
const personsObject = JSON.parse(personsJson);
const personsMap = new Map(Object.entries(personsObject));
for (const key of personsMap.keys()) {
console.log(typeof key)
}
But there is one issue about which you have to be careful. Key of the map created in that way will always be a STRING. It will happen, because KEY of JSON object is always a STRING. So if your Map keys should be numbers then first you have parse keys of your object entries.
From JSON to Map (number keys)::
const personsJson = `{"1":{"firstName":"Jan","lastName":"Kowalski"},"2":{"firstName":"Justyna","lastName":"Kowalczyk"}}`;
const personsObject = JSON.parse(personsJson);
const personObjectEntries = Object.entries(personsObject);
const personObjectEntriesNumberKeys = personObjectEntries.map(person => {
person[0] = parseInt(person[0]);
return person;
});
const personsMap = new Map(personObjectEntriesNumberKeys);
for (const key of personsMap.keys()) {
console.log(typeof key)
}
There is person[0] because under 0 index there is the key of the object

You can copypaste this function: it would take JSON and return a Map of Maps:
It works with this JSON:
{
"data":{
"1":{
"color":"red",
"size":"big"
},
"2":{
"color":"red",
"size":"big"
},
"3":{
"color":"red",
"size":"big"
},
"4":{
"color":"red",
"size":"big"
},
"5":{
"color":"red",
"size":"big"
}
}
}
function jsonToMap(jsonString) {
var jsonObject = JSON.parse(jsonString);
var dataObject = jsonObject.data;
var dataMap = new Map(Object.entries(dataObject));
var resultMap = new Map();
for (const key of dataMap.keys()) {
console.log(key);
var keyMap = new Map(Object.entries(dataMap.get(key)));
resultMap.set(key, keyMap);
}
console.log("done!");
return resultMap;
}

Related

Join elements of an object and exclude some

I have a Typescript project where I want to join all the values of an Object except one.
This is my Object:
let dataInit = {
"host": "CAPR",
"ua": "RMA",
"country": "VE",
"page":3
};
This is what I do:
let dataJoin = Object.values(dataInit).join(',')
This is what I get:
CAPR,RMA,VE,3
I need to know how to remove the 'page' property, this is what I want:
CAPR,RMA,VE
If you don't know the other attributes, you can first use Object.entries() to give you an array of arrays containing the keys and values. That array can then be filtered to remove the "page" element, mapped to just contain the value, and finally joined.
let dataInit = {
"host": "CAPR",
"ua": "RMA",
"country": "VE",
"page":3
};
console.log(
Object.entries(dataInit)
.filter(([key,val]) => key !== "page")
.map(([_,val]) => val)
.join(",")
)
I would destructure the object first and create a new one
const { host, ua, country } = dataInit
const dataNew = { host, ua, country }
And then call the values join method on the new object.
You could filter the array resulted:
let dataJoin = Object.values(dataInit).filter(element => typeof element === "string").join(",");
Or you can use destructuring as presented in the other comments.
You can use for...in loop to iterate over element and skip page property.
let dataInit = {
"host": "CAPR",
"ua": "RMA",
"country": "VE",
"page": 3
};
const convertObject = (obj) => {
let list = [];
for (const prop in obj) {
if (prop !== "page") {
list.push(obj[prop]);
}
}
return list.join(",");
}
console.log(convertObject(dataInit));

How to parse JS Object containing arrays to use in json2csv module in JavaScript?

I have an array(arr) of objects where each object looks like this:-
{
"name" : "someName",
"address" : "someAddress",
"attributes" : [
{
"attName" : "Sea",
},
{
"attName" : "Beach",
}
],
"values" : [
"2540",
"3345",
"2340"
]
}
The arrays "values" and "attributes" may have different number of elements for different objects.
Now when I convert this array of objects to csv using this code:
const json2csv = require('json2csv').parse;
const csvString = json2csv(arr);
I get the following output:
name, address, attributes, values
"someName","someAddress", [{"attName" : "Sea"},{"attName" : "Beach"}], ["2540", "3345", "2340"]
However, I want my csv something like this:
name, address, attName, attName, value, value, value
"someName","someAddress", "Sea", "Beach", "2540", "3345", "2340"
I know that JSON doesn't allow multiple keys with same name but I can't figure out how to achieve this.
Expanding an array column into multiple column of the same title is non-standard.
However, if you really wants to do that, you can write a custom function to convert the object array into a 2D string array. Then use a library to convert the 2D string array into csv.
For example:
// import a library to convert 2d string array into csv string
let { to_csv } = require("#beenotung/tslib/csv");
// the sample object array
let records = [{
"name": "someName",
"address": "someAddress",
"attributes": [
{
"attName": "Sea",
},
{
"attName": "Beach",
}
],
"values": [
"2540",
"3345",
"2340"
]
}];
let csv = object_array_to_csv(records)
console.log(csv);
/* will print out below lines:
name,address,attName,attName,values,values,values
someName,someAddress,Sea,Beach,2540,3345,2340
*/
// convert an object array into csv text
function object_array_to_csv(objects) {
let records = objects.map(object_to_opt_list);
let titles = records.find(record => record.length > 0)
.map(field => field.key);
let values = records.map(record => record.map(field => field.value));
let rows = [titles, ...values];
let csv = to_csv(rows);
return csv;
}
// convert an object with string and array of string/object into 2d key-value array
function object_to_opt_list(object) {
let opt_list = [];
for (const [key, value] of Object.entries(object)) {
if (Array.isArray(value)) {
opt_list.push(...value_to_opt_list(key, value));
}
else {
opt_list.push({ key, value });
}
}
return opt_list;
}
// convert recursively expand the array/object value into 2d key-value array
function value_to_opt_list(key, value) {
if (Array.isArray(value)) {
return value.map(value => value_to_opt_list(key, value))
.reduce((acc, c) => acc.concat(c));
}
if (typeof value === "object") {
return object_to_opt_list(value);
}
return [{ key, value }];
}

Javascript get key of nested JSON object?

I have a json response that looks like the image below. I want to get all dates from the json and store in an array.
function buyOption(){
var ticker = document.getElementById('ticker').value;
fetch("https://stock-and-options-trading-data-provider.p.rapidapi.com/options/JPM", {
.then(response => response.json())
.then(data => {
dataset = data;
console.log(dataset['options'])
loadTable()
})
.catch(err => {
console.log(err);
});
function loadTable(){
expiration_dates = []
dates = dataset['options']
// console.log(JSON.parse(dates))
var keys = [];
for(var k in dates) keys.push(k);
console.log(keys)// returns ["0","1","2",3","5",6","9","10","11"]
console.log(dates[0].value) // returns undefined
}
}
goal is to have expiration_dates = ["2020-08-21","2020-08-28"]
You can try this. This will give you only the expiration dates.
var obj = {
"options": [{
"10-2-2001": "",
"someOtherProp": ""
}, {
"20-2-2001": "",
"someOtherProp": ""
}]
}
var expDates = obj.options.map(o=>Object.keys(o)[0])
console.log(expDates)
Refs:
Array.map()
Object.keys()
Try this
let result = dataSet.options.map(x => Object.keys(x));
console.log(result.flat(1))
A simple array map should do the trick and use Object.keys() array to get first key from each object in your data array
const dates = dataset['options'].map(o => Object.keys(o)[0])
console.log(dates)
<script>
const dataset = {
options: [{
'2013-12-22': {
puts: [],
calls: []
}},
{'2013-02-15': {
puts: [],
calls: []
}},
{ '2018-01-01': {
puts: [],
calls: []
}}
]
}
</script>
Something like
const options=dates.options.map(o=>
Object.keys(o).filter(k=>k.match(/^2\d{3}-\d{2}-\d{2}$/))[0]);
The idea is to loop over all options, get all keys for each of the objects and filter out the keys matching the Regexp, which is a date format, starting with 2. From the filtered keys-array I am only interested in the first element ([0]).
for(k in dates) {
keys.push((v=>{
for(let i in v) return i;
})(dates[k]));
}
Try it

How to rename JSON element in Nodejs

I have an API that response JSON data like this-
{
"unitcode":"apple",
"description":"bus",
"color":"red",
"intent":"Name 1"
}
I want to change like this-
{
"Value1":"apple",
"Value2":"bus",
"value3":"red",
"value4":"sale"
}
Presently, I can code to rename single key but i want some code to replace all key in one shot. my code like this-
request(baseurl)
.then( body => {
var unit = JSON.parse(body);
unit.intent = "sales"
unit.value1 = unit.unitcode
delete unit.unitcode;
console.log(unit)
console.log(unit.Value1)
var unit2 = JSON.stringify(unit)
// let code = unit.description;
conv.ask('Sales is 1 million metric tonnes ' + unit2);
})
please help me out on this and please little elaborate also to learn something new. thanks
Create a Map of original key to new key (transformMap). Convert the object to pairs of [key, value] with Object.entries(), iterate with Array.map() and replace the replacement key from the Map (or the original if not found). Convert back to an object with Object.toEntries():
const transformMap = new Map([
['unitcode', 'Value1'],
['description', 'Value2'],
['color', 'Value3'],
['intent', 'Value4']
]);
const transformKeys = obj =>
Object.fromEntries(
Object.entries(obj)
.map(([k, v]) => [transformMap.get(k) || k, v])
);
const obj = {
"unitcode": "apple",
"description": "bus",
"color": "red",
"intent": "Name 1"
};
const result = transformKeys(obj)
console.log(result)
If you know the object structure and it is constant, you could just use destructing like so.
const data = {
"unitcode":"apple",
"description":"bus",
"color":"red",
"intent":"Name 1"
};
// If the object is fixed and the fields are known.
const mapData = ({ unitcode, description, color, intent }) => ({
Value1: unitcode,
Value2: description,
Value3: color,
Value4: intent
});
console.log(JSON.stringify(mapData(data)));
But if the object has an unknown number of properties:
const data = {
"unitcode":"apple",
"description":"bus",
"color":"red",
"intent":"Name 1"
};
// If the object is fixed and the fields are known.
const mapData = (data) => {
return Object.keys(data).reduce((a,v,i) => {
a[`Value${i+1}`] = data[v];
return a;
}, {});
};
console.log(JSON.stringify(mapData(data)));
You can edit the array to have the values you need
let i=0,j=0,unit1={};
let unit = JSON.parse(body);
let unit3=["val1","val2","val3","val4"]
let unit5=Object.values(unit);
for(let key in unit){
unit1[unit3[i++]]=unit5[j++];
}
var unit2 = JSON.stringify(unit1)
console.log('Sales is 1 million metric tonnes \n' + unit2);
//Sales is 1 million metric tonnes
//{"val1":"apple","val2":"bus","val3":"red","val4":"Name 1"}
Well your target is to modify the keys and retain the value
In that context, you can iterate through your data. To dynamically generate keys as Value1, Value2, etc, we will append Value with iteration index which is going to be unique always.
const modifyInput = (input) => {
const modifiedInput = {}
Object.values(input).forEach((item, index) => {
modifiedInput[`Value${index + 1}`] = item
})
return modifiedInput
}
Use this function, pass your input and get your desired result

Set First Value as Key in Javascript Array

Creating an array based off selected DataTables Rows
$('#savenlp').click(recordjourney);
function recordjourney() {
var data = table.rows(['.selected']).data().toArray();
console.log( (data) );
console.log( JSON.stringify(data) );
}
data returns
0 : (8) ["Which", "TitleCase", "QuestionWord", "", "", "", "", ""]
JSON.stringify(data) returns
[["baseball","Noun","Singular","","","","",""]]
This information is dynamically generated, so I am just looking to take the first value (in this case baseball) and turn it into something like
"baseball": [
"Noun",
"Singular"
]
I can return the first value (the key I want using)
alert(data[0][0]);
I am much more adept in PHP but I am learning javascript/jquery more and more.
It is my understanding javascript does not have associative arrays, so I am a bit confused as to how to generate this.
const data = [
["baseball","Noun","Singular","","","","",""],
["baseballs","Noun","","Plural","","","","",]
];
const mappedData = data.reduce((acc, row) => { acc[row.shift()] = row.filter(d => d !== ''); return acc; }, {});
console.log(mappedData);
We can use object destructuring and spread operators for ease of use.
In the example below, the key will be the first item and all the rest items will be placed in the newData variable
const data = [["baseball","Noun","Singular","","","","",""]];
const [key, ...newData] = data[0]
// if you want the new data to not have empty entries, simple apply the filter
const newDataFiltered = newData.filter(item => !!item)
const objWithEmpty = {[key]: newData}
const objWithoutEmpty = {[key]: newDataFiltered}
console.log(objWithEmpty, objWithoutEmpty)
For multiple arrays inside the outer array, just enclose the whole logic inside a for loop
const data = [
["baseball","Noun","Singular","","","","",""],
["baseball1","Noun1","Singular1","","","","",""],
["baseball2","Noun2","Singular2","","","","",""]
];
const objWithEmpty = {}
const objWithoutEmpty = {}
data.forEach((array) => {
const [key, ...newData] = array
// if you want the new data to not have empty entries, simple apply the filter
const newDataFiltered = newData.filter(item => !!item)
objWithEmpty[key] = newData
objWithoutEmpty[key] = newDataFiltered
})
console.log(objWithEmpty, objWithoutEmpty)
Simply extract the desired values from data and put them into an object formatted as you like:
const data = [["baseball","Noun","Singular","","","","",""]];
const firstArr = data[0];
const transformedFirstObject = {
[firstArr[0]]: [firstArr[1], firstArr[2]],
};
console.log(transformedFirstObject);
But it's pretty weird to have an object with only one property like that. If your data might have more than one sub-array in it and you want to turn the array of arrays into an array of objects, use map:
const data = [
["baseball","Noun","Singular","","","","",""],
["foo","bar","baz","","","","",""]
];
const transformed = Object.assign(...data.map(([prop, value1, value2]) => ({ [prop]: [value1, value2] })));
console.log(transformed);
A bit simpler compared to other answers here but works as well.
const data = [
["baseball","Noun","Singular","","","","",""],
["baseball1","Noun1","Singular1","","","","",""],
["baseball2","Noun2","Singular2","","","","",""]
];
const obj = [];
data.forEach(function(i) {
let jsonObj = {};
jsonObj [i[0]] = i.slice(1).filter(x=>x !='');
obj.push(jsonObj)
});
console.log(JSON.stringify(obj))
Just using forEach, considering multiple array elements.
var obj = {};
var arr = [
["baseball", "Noun", "Singular", "", "", "", "", ""],
["Test", "Test1", "Test2", "", "", "", "", ""]
];
arr.forEach(function(val, idx) {
val.forEach(function(val1, idx1) {
if (idx1 === 0) {
obj[val1] = val.slice(1, val.length)
}
})
})
console.log(JSON.stringify(obj))

Categories

Resources