How to push JSON data in two dimensional array? - javascript

I am trying to get a structure like
var tableData= [
['Hfbj'],
['Hygh'],
[6],
['mayur'],
[2563458952]
]
Here is my JSON data:
data:{
"address"': "Hfbj"
"id": 6
"landmark": "Hygh"
"name": "mayur"
"phone": 2563458952
"title": "aaa"
}
I am using react-native-table-component in which that type of structure needed. For that, I am doing the following but it showing data.map is not function and undefined.
let newdata = this.state.tableData[0].push(
[responseJson.data.title],
[responseJson.data.title]
);
this.setState({
tableData: newdata
});
How can I achieve it?

You could make use of Object.values and Array.map:
var reponseJson = {
data: {
"address": "Hfbj",
"id": 6,
"landmark": "Hygh",
"name": "mayur",
"phone": 2563458952,
"title": "aaa"
}
};
var newData = Object.values(reponseJson.data)
.map(item => [item]);
console.log(newData);
Note that I used the responseJson name to match your question, but as #Andreas pointed out, this is an object, not JSON.
If you need only certain columns (as requested in the comments below), use Object.keys and Array.filter on them before rebuilding the array:
var reponseJson = {
data: {
"address": "Hfbj",
"id": 6,
"landmark": "Hygh",
"name": "mayur",
"phone": 2563458952,
"title": "aaa"
}
};
var keysToKeep = ['address', 'landmark', 'title'];
var newData = Object.keys(reponseJson.data)
.filter(key => keysToKeep.includes(key))
.map(key => [reponseJson.data[key]]);
console.log(newData);

.map Is for arrays, whereas your responseJson.data is an Object. To get turn that Object into an array of its values you can do Object.values(responseJson.data)

Related

Update a nested object in JavaScript

This is the original data
const data = {
"field1": {
"name": 'Anuv',
"marks": {
"eng": 43,
"hindi": 23
},
"age": 21
},
"field2": {
"school": 'DAV'
}
}
I am trying to update the name
const updatedValue = {
"field1": {
"name": "Anuv Gupta"
}
}
This is the expected data. It should have all the field and the updated name value as well.
const expectedData = {
"field1": {
"name": 'Anuv Gupta',
"marks": {
"eng": 43,
"hindi": 23
},
"age": 21
},
"field2": {
"school": 'DAV'
}
}
I have tried using these
expectedData = Object.assign({}, data, updatedValue)
as well as
expectedData = { ...data, ...updatedValue },
both of them returns this object
const obj = {
"field1": {
"name": 'Anuv Gupta',
},
"field2": {
"school": 'DAV'
}
}
How do I fix this and get the expectedData object?
If you don't care about mutating your original data you can just do:
data.field1.name = 'Anuv Gupta';
console.log(data);
If you don't want your original data to mutate, just clone it first and do the new value assignment:
const dataClone = structuredClone(data);
dataClone.field1.name = 'Anuv Gupta';
console.log(dataClone);
Edit:
Like others suggested you can also achieve that by spreading your data object into a new one like so:
const newData = {
...data,
field1: {
...data.field1,
name: 'Anuv Gupta',
}
}
It works but it is not mutation proof as it only shallow clones the original data object - You can read more about shallow vs deep clone in this great blog post. if you care about not mutating your original data, I would use the second option I mentioned in my answer
Avi's answer is good. Just to add one more method that is strictly immutable, you could do the following:
const expectedData = {
...data,
"field1": {
...data.field1,
"name": 'Anuv Gupta',
}
}
You can access the name property directly:
data.field1.name = "new value"
If you're trying to avoid mutating the original data obj you can try:
data2 = Object.assign({}, data);
data2.field1.name = "new value"
just change it directly using an Object property
data.field1.name = 'anuv Gupta'
and don't use quotes for object keys just do this and it works just fine
const obj = {
field1: {
name: 'Anuv Gupta',
},
field2: {
"school": 'DAV'
}
}

How To Add A String Inside An Object For The Given Example

Hi iam finding the best way to add a string inside the given object.Any help would be appreciated
my String is 'created'
Down Below Is My Data
{
"id": "222",
"list": [
{
"name": "Tony",
}
],
iam trying to insert 'created' in the data like this
{
"id": "222",
"list": [
{
"name": "Tony",
"type":"created"
}
]
The string you've provided looks a lot like JSON data. You can convert a JSON string to an actual javascript object by using the JSON.parse(string) method.
With this object we then can query it's list property - which in your case is an array of objects - and add a new property type to each of the arrays elements. The final step is converting the object back to a JSON string using the JSON.stringify(object) method.
Here's an example:
let str = `{
"id": "222",
"list": [
{
"name": "Tony"
}
]
}`;
let data = JSON.parse(str);
data.list.forEach(element => {
element.type = "created";
});
str = JSON.stringify(data);
console.log(str);
const myObj = {
"id": "222",
"list": [
{
"name": "Tony",
}
],
};
myObj.list[0].type = "created";
This is the way you can do this. But you'd better use secified index of list items;
const index = 0; // Or any other way to get this
myObj.list[index].type = "created";

Normalize objects in array such that all contain the same set of keys

I am hitting an endpoint that is returning an array of objects, each object can potentially have a set of fields, e.g.,
const FIELDS = [
'id',
'title',
'contributor',
'mediatype',
'source'
]
However, some objects will only have some of those fields, some may have all.
const items = [
{
"id": 1,
"title": "some title 1",
"contributor": "bob",
"mediatype": "text"
},
{
"id": 2,
"title": "some title 2",
"mediatype": "text"
}.
{
"id": 3,
"title": "some title 3",
"mediatype": "movies"
"source": "comcast"
}
]
I want to "normalize" all the objects such that every single one contains every expected field, filling the "gaps" with null, or some falsey value such that graphql (which I intend to eventually feed it into) is happy.
const items = [
{
"id": 1,
"title": "some title 1",
"contributor": "bob",
"mediatype": "text",
"source": null
},
{
"id": 2,
"title": "some title 2",
"mediatype": "text",
"contributor": null,
"source": null
}.
{
"id": 3,
"title": "some title 3",
"mediatype": "movies",
"contributor": null,
"source": "comcast"
}
]
My "nasty" looking code looks something like this
const normalize = items =>
items.map(item => {
FIELDS.forEach(f => {
if (!item[f]) {
item[f] = null;
}
});
return item;
});
Any suggestions for writing this more elegantly - either with vanilla JS or lodash, which I am equally open to using as its already available in my codebase?
You can use spread syntax, but then it would be better to define FIELDS as a template object:
const FIELDS = {
id: null,
title: null,
contributor: null,
mediatype: null,
source: null
};
const normalize = items => items.map(item => ({...FIELDS, ...item}));
Your if (!item[f]) test will match on any falsy value, which is probably not what you want.
Instead, you should properly check if the key exists, e.g.:
if (!(f in item))
Not sure if this is any better really... but here is some equivalent alternative syntax.
Use an "equals itself or null" to squeeze out a bit more sugar:
const normalize = items =>
items.map(item => {
FIELDS.forEach(f => item[f] = item[f] || null);
return item;
});
Or test everyone's patience with this one liner:
const normalize = items =>
items.map(item => FIELDS.reduce((acc, field) => {acc[field] = item[field] || null; return acc}, item));
The choice is yours.

converting array to object while considering keys of the same value

I am trying to figure out an easy way to convert an array of objects to an object
I have an array of objects that looks like this:
[
{
"id": "-LP9_kAbqnsQwXq0oGDT",
"value": Object {
"date": 1541482236000,
"title": "First",
},
},
.... more objects here
]
And id like to convert it to an object with the timestamps as the keys, and arrays of objects corresponding to that date. If that key already exists, then add the object to the corresponding array associated with that key
{
1541482236000:
[{
"id": "-LP9_kAbqnsQwXq0oGDT",
"value": Object {
"date": 1541482236000,
"title": "First",
},
},
{
"id": "-LP9_kAbqnsQwXqZZZZ",
"value": Object {
"date": 1541482236000,
"title": "Some other title",
},
},
.... more objects here
],
1541482236001:
[{
"id": "-LP9_kAbqnsQ1234",
"value": Object {
"date": 1541482236001,
"title": "Another title",
},
},
.... more objects here
]
}
I was able to achieve something similar using reduce. However it does not handle adding objects to the array when their key already exists.
calendarReminders = action.value.reduce((obj, reminder) => {
dateKey = moment(reminder.value.date).format('YYYY-MM-DD')
obj[dateKey] = [reminder]
return obj;
}, {});
How can I do this?
You just need to check whether the object is already a key and if not add it with the value of an array. Then you can just push() into it:
let arr = [{"id": "-LP9_kAbqnsQwXq0oGDT","value": {"date": 1541482236000,"title": "First",},},{"id": "SomID","value": {"date": 1541482236000,"title": "Some other title",},},{"id": "A different ID","value": {"date": 1541482236001,"title": "A third title",},}]
let calendarReminders = arr.reduce((obj, reminder) => {
(obj[reminder.value.date] || (obj[reminder.value.date] = [])).push(reminder)
return obj;
}, {});
console.log(calendarReminders)
If you want to set the keys to a different format with moment, you should be able to do that without changing the basic idea.
Please test the below code!
First you iterate through your array of data,
if your result object/dictionary already has the key then you just add the current item
otherwise you make the key and set the value
const data = [];
let result = {};
for (const item of data) {
const key = item.value.date;
if (result.hasOwnProperty(key)) {
const prevData = result[key];
result[key] = [...prevData, item];
} else {
result[key] = [item];
}
}

How to create a new json out of three jsons?

I have 3 different jsons, I need to extrapolate some data from each and create a new json with it. The three jsons have an id identifier in common, a unique identifier, so We could use that as a match since they are actually three different big jsons.
On json one we have "id":"265", on two and three "article_id":"265", so these can be the reference point when we loop.
I never worked with json this way so I wouldn't know how to approach it. I have put jQuery and JS as tags as they're what I know best.
1
{
"id":"265",
"title":"Battle of Gettysburg",
"page_id":"4849",
"language_id":"en",
"original_time":"July 1\u20133, 1863"
}
2
{
"id":"185",
"original_name":"United States",
"country_id":"24",
"article_id":"265"
}
3
{
"id":"73",
"month":"July",
"year":"1863",
"suffix":"",
"article_id":"265"
}
So the end result I am looking for is a single json exactly like this, we take id and title as objects from json 1, then we grab original_name from json two and year object from json three and we'll have:
{
"id":"265",
"title":"Battle of Gettysburg",
"original_name":"United States",
"year":"1863"
}
NOTE
The json above are just examples, in reality they are three huge lists, what I could do (manually), is to join them in order to have a single json.
There is some terminology confusion here; based on your comments you could be asking one of two very different questions. Fortunately one of them is very simple to answer so let's do both.
(I am handwaving past the details of loading json strings into the browser and converting them into javascript objects.)
If you have three objects
...then this is just a matter of plucking out the fields you need individually when constructing an output object:
var in1 = {
"id": "265",
"title": "Battle of Gettysburg",
"page_id": "4849",
"language_id": "en",
"original_time": "July 1\u20133, 1863"
};
var in2 = {
"id": "185",
"original_name": "United States",
"country_id": "24",
"article_id": "265"
}
var in3 = {
"id": "73",
"month": "July",
"year": "1863",
"suffix": "",
"article_id": "265"
}
// construct a new object using the selected fields
// from each object in1, in2, or in3:
var out = {
id: in1.id,
title: in1.title,
original_name: in2.original_name,
year: in3.year
}
console.log(out);
If you have three lists of objects:
...in this case it's a lot more complicated (and a lot more interesting). In this case you would need to match fields from the objects in each list which share the same IDs.
The following is definitely not the most efficient or memory-conserving way to do this; I've spread things out to (hopefully) make it easier to follow what it's doing.
I'm making two assumptions:
within each list, all IDs are unique (meaning you won't have two objects with the same ID in one JSON file)
Every ID will appear in all three lists (meaning you don't need to handle missing fields in output)
/* Again handwaving past loading JSON strings and parsing
them into javascript objects, we'll just start with
three arrays: */
var input1 = [{
"id": "265",
"title": "Battle of Gettysburg",
"page_id": "4849",
"language_id": "en",
"original_time": "July 1\u20133, 1863"
},
{
"id": "1",
"title": "Foo",
"page_id": "123",
"language_id": "en",
"original_time": "July 1\u20133, 1863"
}
];
var input2 = [{
"id": "1",
"original_name": "Bar",
"country_id": "24",
"article_id": "265"
},
{
"id": "265",
"original_name": "United States",
"country_id": "24",
"article_id": "265"
}
]
var input3 = [{
"id": "1",
"month": "July",
"year": "Baz",
"suffix": "",
"article_id": "265"
},
{
"id": "265",
"month": "July",
"year": "1863",
"suffix": "",
"article_id": "265"
}
]
/* It would be much easier to find corresponding IDs
across these arrays if they weren't arrays. We'll
start by converting them into objects keyed by the
item ids: */
var convertArray = function(arr) {
var output = {};
arr.forEach(function(o) {
output[o.id] = o;
});
return output;
}
var obj1 = convertArray(input1);
var obj2 = convertArray(input2);
var obj3 = convertArray(input3);
/* Now if we need to find (say) the object with id "foo", we don't
need to search the whole array, but can just use `obj1["foo"]` or
`obj1.foo`.
The last step is to iterate over the list of IDs and repeatedly
do basically the same thing as in the "if you have three objects"
part above. The only difference is that we need to access the
object with the same ID in each of the input lists: */
var constructOutput = function(in1, in2, in3) {
var output = []; // we'll be outputting a list of objects again.
// step through every ID (assuming in1 contains all of them):
Object.keys(in1).forEach(function(id) {
var obj = {
id: id,
title: in1[id].title,
original_name: in2[id].original_name,
year: in3[id].year
}
output.push(obj);
});
return output;
}
var final = constructOutput(obj1, obj2, obj3)
console.log(final)
Essentially what you have to do is mimic a SQL JOIN using JavaScript objects:
Use JSON.parse() on all three JSON collections to turn them into arrays of objects.
Iterate through JSON 1 objects; for each object...
Iterate through JSON 2 objects, testing if article ID matches the ID from JSON 1 that we are iterating over. Save this object.
Iterate through JSON 3 objects, testing if ID matches the ID of the object we found from JSON 2. Save this object.
After you have all three objects, make a new object literal that contains only the fields you want:
{
Id: obj1.id,
Title: obj1.title,
Original_name: obj2.original_name,
Year: obj3.year
}
Should you want to combine n number of JSON objects, e.g. a list of objects you can take a functional approach and utilise reduce + filter.
const data = [{
"id":"265",
"title":"Battle of Gettysburg",
"page_id":"4849",
"language_id":"en",
"original_time":"July 1\u20133, 1863"
},
{
"id":"185",
"original_name":"United States",
"country_id":"24",
"article_id":"265"
},
{
"id":"73",
"month":"July",
"year":"1863",
"suffix":"",
"article_id":"265"
}];
const final = data.reduce((accu, { id, title }, index, array) => {
// Find any related objects
const matches = array.filter(data => data.article_id === id);
if (matches.length) {
// Flatten them for ease of access. Duplicate keys will override.
const flat = matches.reduce((arr, item) => ({ ...arr, ...item }), [])
// Return new object
return accu.concat({
...flat,
id,
title,
});
}
return accu;
}, []);
console.log(final, '<<')
// Witness
document.getElementById('results').innerHTML = JSON.stringify(final);
<div id="results" style="font-family: Courier; font-size 14px; color: #fff; background: #000; padding: 20px; max-width: 80vw;"></div>
Edited*
Maybe this is what you need?
let arrPages = [{
"id":"265",
"title":"Battle of Gettysburg",
"page_id":"4849",
"language_id":"en",
"original_time":"July 1\u20133, 1863"
}];
let arrArticles = [{
"id":"185",
"original_name":"United States",
"country_id":"24",
"article_id":"265"
},
{
"id":"73",
"month":"July",
"year":"1863",
"suffix":"",
"article_id":"265"
}];
let getResult = (arrInput, arrCompare) => {
let joinedItems = [];
arrInput.forEach(item => {
let newItem = { id: item.id, title: item.title };
arrCompare.forEach(subItem => {
if(subItem.article_id !== undefined && subItem.article_id === item.id){
if(subItem.original_name !== undefined)
newItem.original_name = subItem.original_name;
if(subItem.year !== undefined)
newItem.year = subItem.year;
}
});
joinedItems.push(newItem);
});
return joinedItems;
};
let result = getResult(arrPages, arrArticles);
console.log(result);
In the first part of the code i create a var that has the json data.
To solve the problema i create 2 functions, the order of the creation dosen't metter, the first function getJSONData() take the json data as parameter and return a object filtered by the keys defined in the array keys. The secound function just check if the current key is present in the array of keys, this function could be replaced by the jQuery.inArray() method.
// JSON data
var json = [{
"id":"265",
"title":"Battle of Gettysburg",
"page_id":"4849",
"language_id":"en",
"original_time":"July 1\u20133, 1863"
},
{
"id":"185",
"original_name":"United States",
"country_id":"24",
"article_id":"265"
},
{
"id":"73",
"month":"July",
"year":"1863",
"suffix":"",
"article_id":"265"
}]
// keys that i want
var keys = ["title", "original_name", "year"];
// var that will have the filtered data
var newJSON = getJSONData(json);
console.log(JSON.stringify(newJSON))
// this is the main function of the code
// here we iterate in the json creating a new object that has all the tags definid in the keys array
function getJSONData(arrayJSON){
var JSONFiltered = {};
for(var i in arrayJSON){
for(var key in arrayJSON[i]){
if(hasElement(key)){
JSONFiltered[key] = arrayJSON[i][key];
}
}
}
return JSONFiltered;
}
// this function is used to check a key is present in the array of keys
function hasElement(key){
for(var elem in keys){
if(keys[elem] == key) return true;
}
return false;
}

Categories