Filter Json Using Javascript - javascript

Hello Can you help me to filter such Json Object:
{
"data": {
"statuses": [{
"entities": {
"urls": [],
"user_mentions": [{
"screen_name": "name1"
}]
},
"entities": {
"urls": [],
"user_mentions": [{
"screen_name": "name2"
}]
},
"entities": {
"urls": [],
"user_mentions": [{
"screen_name": "name3"
}]
}
}]
}
}
I need to get array with values of each key screen_name.
For example: array = ["name1","name2","name3"]
How i can do it without frameworks with only JS?
Thanks for your help. I have updated Json to such like this:
var obj = {
"data": {
"statuses": [{
"urls": [],
"user_mentions": [{
"indices": [
3,
16
],
"id_str": "626444770",
"id": 626444770,
"name": "katheryn",
"screen_name": "sella_sandra"
}, {
"indices": [
"***",
"***"
],
"id_str": "21447363",
"id": 21447363,
"name": "KATY PERRY",
"screen_name": "katyperry"
}, {
"indices": [
"***",
"***"
],
"id_str": "21447363",
"id": 21447363,
"name": "KATY PERRY",
"screen_name": "floyd"
}]
}]
}
I'm wanna to get array of screen_names.I wrote such code.But when i use for.It doesn't work here:
console.log (statuses[0].user_mentions[i].screen_name)
I't silly mistake but I cannot find out how correct that. Help guys!
var statuses = obj.data.statuses;
for (var i=0; i<statuses.length; i++ )
{ if ( typeof statuses[0].user_mentions !== "undefined")
{
for (var i=0; i<statuses.length; i++){
console.log (statuses[0].user_mentions[i].screen_name);
}
}
else console.log ="No senders";
}

Your syntax is incorrect, since inside statuses array you cannot have another key value data.
Removing the entities key name assuming that it is simply an array of objects then try this
var obj = { "data": {
"statuses": [
{
"urls": [],
"user_mentions": [{
"screen_name": "name1"
}]
},
{
"urls": [],
"user_mentions": [{
"screen_name": "name2"
}]
},
{
"urls": [],
"user_mentions": [{
"screen_name": "name3"
}]
}
]
} };
var statuses = obj.data.statuses;
var names = [];
for (var counter = 0; counter < statuses.length; counter++ )
{
names.push( statuses[ counter ].user_mentions[0].screen_name );
}
console.log( names );

Given your updated data object, this returns an array of screen_names (with any duplicates removed. If you want to keep duplicates, declare names as an array and push to it instead.) I used a relatively verbose coding style to make it easier to see what's going on.
var obj = {
"data": {
"statuses": [{
"urls": [],
"user_mentions": [{
"indices": [3,16],
"id_str": "626444770",
"id": 626444770,
"name": "katheryn",
"screen_name": "sella_sandra"
}, {
"indices": ["***","***"],
"id_str": "21447363",
"id": 21447363,
"name": "KATY PERRY",
"screen_name": "katyperry"
}, {
"indices": ["***","***"],
"id_str": "21447363",
"id": 21447363,
"name": "KATY PERRY",
"screen_name": "floyd"
}]
}]
}
};
var names = {};
for (var i=0; i<obj.data.statuses.length; i++) {
if (obj.data.statuses[i]["user_mentions"]) {
var mentions = obj.data.statuses[i]["user_mentions"];
for (var j=0; j<mentions.length;j++) {
if (mentions[j]["screen_name"]) {
names[mentions[j]["screen_name"]] = 1;
}
}
}
}
var arrayOfScreenNames = Object.keys(names);
console.log(arrayOfScreenNames);

Related

Reducing values array of objects to an array without duplicates using Set

I have following array of object:
[{
"user": {
"tags": [{
"tag": "T1"
},{
"tag": "T2"
}]
}
},
{
"user": {
"tags": [{
"tag": "T2"
}]
}
}, {
"user": {
"tags": [{
"tag": "T3"
}]
}
}]
And need to collect all the tags with no duplicates as below using ES6 Set
["T1","T2","T3"]
Can any one help me?
I agree with the comments. Here's a nested loop implementation,
const data = [{
"user": {
"tags": [{
"tag": "T1"
},{
"tag": "T2"
}]
}
},
{
"user": {
"tags": [{
"tag": "T2"
}]
}
}, {
"user": {
"tags": [{
"tag": "T3"
}]
}
}];
const tagsSet = new Set([]);
data.forEach(val => {
val.user.tags.forEach(t => {
if(!tagsSet.has(t.tag)){
tagsSet.add(t.tag);
}
});
});
console.log(tagsSet); // Set(3) {"T1", "T2", "T3"}
Got the answer using reduce and Set. Thanks T.J.Crowder !
const data = [{
"user": {
"tags": [{
"tag": "T1"
},{
"tag": "T2"
}]
}
},
{
"user": {
"tags": [{
"tag": "T2"
}]
}
}, {
"user": {
"tags": [{
"tag": "T3"
}]
}
}];
let uniqueTags = []
const allTags = data.reduce((current , next) => {
current.user.tags.push(...next.user.tags);
return current;
});
uniqueTags = [... new Set(allTags.user.tags.map(t => t.tag))];
console.log(uniqueTags);

o["postmore"] is not iterable

I want to transform created_time from CST to ISOString(ex:2019-02-22T17:43:05.000Z), so i need to get created_time.
But I have the question. When I use for(let...of...){} , I get the error
"o.postmore is not iterable".
How to fixed the codes to get created_time and transform the time?
{
"data": [
{
"text1": "123",
"desc": "xyz",
"postmore": [
{
"name": "haha",
"created_time": "2018-08-22 18:30:01 CST+0800"
},
{
"name": "gogo",
"created_time": "2018-08-22 18:30:01 CST+0800"
}]
},
{
"text1": "123",
"desc": "hjk",
"postmore": [
{
"name": "haha",
"created_time": "2018-08-23 18:30:01 CST+0800"
},
{
"name": "gogo",
"created_time": "2018-08-23 18:30:01 CST+0800"
}]
}]
}
this.http.get(url).subscribe(res =>{
this.testapi = res["data"];
for (let o of this.testapi){
o["text1"] = parseInt(o["text1"]);
for(let os of o["postmore"]){
os["created_time"] = new Date().toISOString();
console.log(os["created_time"]);
}
};
)

Nested json object into single json objects with repeating parent details to construct html table

This is a nested json file and I am trying to arrange it in a readable format to display in a table
I tried to manually put all the keys and values with in a for loop but there should be an elegant way to achieve this and hence I am reaching SO.
The actual JSON is quite a nested one and needed time to execute data with 500k rows
The result should be enhanced JSON with parent values appearing for child values as well
var property = {
"data": [{
"ID": "123456",
"name": "Coleridge st",
"criteria": [
{
"type": "type1",
"name": "name1",
"value": "7",
"properties": []
},
{
"type": "type2",
"name": "name2",
"value": "6",
"properties": [
{
"type": "MAX",
"name": "one",
"value": "100"
}, {
"type": "MIN",
"name": "five",
"value": "5"
}
]
},
{
"type": "type3",
"name": "name3",
"value": "5",
"properties": [{
"type": "MAX1",
"name": "one6",
"value": "1006"
}, {
"type": "MIN2",
"name": "five6",
"value": "56"
}]
}
]
},
{
"ID": "456789",
"name": "New Jersy",
"criteria": [
{
"type": "type4",
"name": "name4",
"value": "6",
"properties": [{
"type": "MAX12",
"name": "one12",
"value": "10012"
}, {
"type": "MIN23",
"name": "five12",
"value": "532"
}]
}
]
}]
};
var output = [];
property.data.forEach(function (users) {
var multirows = {
id: users.ID,
name: users.name,
};
for (var i = 0; i < users.criteria.length; i++) {
var criterias = {
type: users.criteria[i].type,
name: users.criteria[i].name,
value: users.criteria[i].value,
}
var mat_contacts_rows;
if (!isEmpty(users.criteria[i].properties)) {
for (var j = 0; j < users.criteria[i].properties.length; j++) {
var property = {
type: users.criteria[i].properties[j].type,
name: users.criteria[i].properties[j].name,
value: users.criteria[i].properties[j].value
};
mat_contacts_rows = { ...multirows, ...{ criteria: criterias }, ...{ properties: property } };
output.push(mat_contacts_rows);
}
} else {
var property = [];
mat_contacts_rows = { ...multirows, ...{ criteria: criterias }, ...{ properties: property } };
output.push(mat_contacts_rows);
}
}
});
console.log(JSON.stringify(output, undefined, 2))
function isEmpty(obj) {
for (var key in obj) {
if (obj.hasOwnProperty(key))
return false;
}
return true;
}
I think this could be a great exercise to you to don't answer your question but to give you some tips. You should first look at : Lodash wish has a bunch of usefull method to help you doing what you'r trying to do.
In a second time you should avoir using .forEach or for loops and try using Array.prototype.map or Array.prototype.reduce

javascript extract objects from nested arrays using a list of ids

I have a list of ids as reference, and I have an object which contains multiple objects that have array of objects.
I want to make an array of objects with corresponding ids in the list, the FASTEST way.
const data = {
"items": {
"item1": [{
"id": "id1",
"info": "info1"
},
{
"id": "id2",
"info": "info22"
}
],
"item20": [{
"id": "id3",
"info": "info5"
}],
"item5": [{
"id": "id4",
"info": "info6"
},
{
"id": "id5",
"info": "info7"
}
]
}
};
const keep = ['id4', 'id2'];
const results = [];
keep.forEach(function(val) {
const match = Object.keys(data.items).map(item => {
return data.items[item].find(obj => obj.id === val)
});
results.push(match)
})
console.log('final: ', results)
the current is not returning what i want.
the expected result will be:
[
{
"id": "id2",
"info": "info22"
},
{
"id": "id4",
"info": "info6"
}
]
update:
How about in the case if the data is itself an array of objects, and we want to do the same for each one?
const data = [{
"otherStuff": "otherB",
"items": {
"item1": [{
"id": "id1",
"info": "info1"
},
{
"id": "id2",
"info": "info22"
}
],
"item20": [{
"id": "id3",
"info": "info5"
}],
"item5": [{
"id": "id4",
"info": "info6"
},
{
"id": "id5",
"info": "info7"
}
]
}
}, {
"otherStuff": "otherA",
"items": {
"item1": [{
"id": "id1",
"info": "info10000"
},
{
"id": "id2",
"info": "info220000"
}
],
"item20": [{
"id": "id3",
"info": "info5000"
}],
"item5": [{
"id": "id4",
"info": "info60000"
},
{
"id": "id5",
"info": "info7000"
}
]
}
}];
const keep = ['id4', 'id2'];
const results = [];
keep.forEach(function(val) {
data.forEach(function(entry){
Object.keys(entry.items).forEach(item => {
var match = entry.items[item].find(obj => obj.id === val);
if (match) {
results.push(match)
}
});
});
})
console.log(results)
and the output should be:
[
{
"otherStuff": "otherB",
"items": [
{
"id": "id2",
"info": "info22"
},
{
"id": "id4",
"info": "info6"
}
]
},
{
"otherStuff": "otherA",
"items": [
{
"id": "id2",
"info": "info220000"
},
{
"id": "id4",
"info": "info60000"
}
]
}
]
the result is not the same though.
If you use a Set for the kept ids, you save one O(n) traversal:
const keep = new Set(['id4', 'id2']);
const result = [];
for(const items of Object.values(data.items))
for(const item of items)
if(keep.has(item.id))
result.push(item);
You do not need to use map(). Simply use forEach() loop on the object keys which you want to keep and find the matching object so that it can be pushed into the result array.
const data = {
"items": {
"item1": [{
"id": "id1",
"info": "info1"
},
{
"id": "id2",
"info": "info22"
}
],
"item20": [{
"id": "id3",
"info": "info5"
}],
"item5": [{
"id": "id4",
"info": "info6"
},
{
"id": "id5",
"info": "info7"
}
]
}
};
const keep = ['id4', 'id2'];
const results = [];
keep.forEach(function(val) {
Object.keys(data.items).forEach(item => {
var match = data.items[item].find(obj => obj.id === val);
if (match) {
results.push(match)
}
});
})
console.log('final: ', results)
items is an object & item1,item20 are are keys.So you can do Object.values and apply reduce function on it to get a single array which is consist of all the objects. No iterate the keep array and filter out the required element from the single array.
const data = {
"items": {
"item1": [{
"id": "id1",
"info": "info1"
},
{
"id": "id2",
"info": "info22"
}
],
"item20": [{
"id": "id3",
"info": "info5"
}],
"item5": [{
"id": "id4",
"info": "info6"
},
{
"id": "id5",
"info": "info7"
}
]
}
};
const keep = ['id4', 'id2'];
let getAllObjectValues = Object.values(data.items).reduce(function(acc, curr) {
curr.forEach((elem) => {
acc.push(elem)
})
return acc;
}, []);
let k = keep.map(function(item) {
return getAllObjectValues.filter(function(val) {
return item === val.id
})[0]
})
console.log(k)
You've used an assignment operator rather than an equivalence operator in your map function, change to:
const keep = ['id4', 'id2'];
const results = [];
keep.forEach(function(val){
const match = Object.keys(data.items).map(item => {
return data.items[item].find(obj => obj.id === val)
});
results.push(match)
})
console.log('final: ', results)
Using a combination of reduce and filter you can iterate each sub-array checking whether the value should be kept.
const data = {
"items": {
"item1": [
{
"id": "id1",
"info": "info1"
},
{
"id": "id2",
"info": "info22"
}
],
"item20": [
{
"id": "id3",
"info": "info5"
}
],
"item5": [
{
"id": "id4",
"info": "info6"
},
{
"id": "id5",
"info": "info7"
}
]
}
};
const keep = ['id4', 'id2'];
const filter = el => {
return keep.indexOf(el.id) >= 0;
};
const reducer = (accumulator, currentValue) => {
return accumulator = accumulator.concat(data.items[currentValue].filter(filter));
};
let results = Object.keys(data.items).reduce(reducer, []);
console.log('final: ', results);

Building new JSON from existing one

I want to build an new JSON from existing one. The source has sections and rubrics that I no longer need for a listing. The new object called 'items' should have an array of the items.
The final JSON should be sorted by attribute 'name' and look like
{
"items": [
{
"id": 10000006,
"name": "Boah"
},
{
"id": 10000013,
"name": "Gut"
},
{
"id": 10000003,
"name": "Ipsum"
},
{
"id": 10000001,
"name": "Lorem"
},
{
"id": 10000005,
"name": "Lorum"
},
{
"id": 10000004,
"name": "Name"
},
{
"id": 10000002,
"name": "Stet"
}
]
}
For building the new JSON I get this source:
{
"sections": [
{
"name": "FooBar",
"rubrics": [
{
"name": "Foo",
"items": [
{
"id": 10000001,
"name": "Lorem"
},
{
"id": 10000002,
"name": "Stet"
},
{
"id": 10000003,
"name": "Ipsum"
}
]
},
{
"name": "Bar",
"items": [
{
"id": 10000004,
"name": "Name"
},
{
"id": 10000005,
"name": "Lorum"
},
{
"id": 10000006,
"name": "Boah"
}
]
}
]
},
{
"name": "BlahBloob",
"rubrics": [
{
"name": "Bla",
"items": [
{
"id": 10000013,
"name": "Gut"
}
]
},
{
"name": "Bloob",
"items": [
{
"id": 10000014,
"name": "Name"
},
{
"id": 10000015,
"name": "Lorem"
}
]
}
]
}
]
}
What do you think? How can I do this with plain JavaScript or maybe TypeScript?
Thanks for reading and have time for my question. And thanks for reply in advance.
Here you go. You just need to iterate over each rubric of each section of your source to get the items. At the end, sort your list of items by items, and you're done.
This example uses ES6 syntax, but it's easy to convert it to ES5 if needed.
function extractItems(source) {
const items = [];
for (const section of source.sections) {
for (const rubric of section.rubrics) {
items.push(...rubric.items);
}
}
items.sort((a, b) => a.name.localeCompare(b.name));
return { items };
}
A more functional approach use map and reduce to pick the rubrics and merge them.
data.sections
.map(section => section.rubrics) // get rubrics
.reduce((a, b) => a.concat(b)) // merge rubrics
.map(rubric => rubric.items) // get items from each rubric
.reduce((a, b) => a.concat(b)) // merge items
.sort((a, b) => a.name.localeCompare(b.name)); // sort
function(oldObj) {
var newObj = {
"items": []
};
oldObj.sections.forEach(function(section) {
section.rubrics.forEach(function(rubric) {
rubric.items.forEach(function(item) {
newObj.items.push(item);
});
});
});
newObj.items = newObj.items.sort(function(a, b) {
if (a.name < b.name) { return -1; }
if (a.name > b.name) { return 1; }
return 0;
});
return newObj;
}
And simply use JSON.parse() and JSON.stringify() to convert JSON to and from objects.
It might help you
var data ={
"sections": [
{
"name": "FooBar",
"rubrics": [{"name": "Foo", "items": [{"id": 10000001,"name": "Lorem"}, {"id": 10000002,"name": "Stet"}, {"id": 10000003,"name": "Ipsum"}]
}, {
"name": "Bar",
"items": [{
"id": 10000004,
"name": "Name"
}, {
"id": 10000005,
"name": "Lorum"
}, {
"id": 10000006,
"name": "Boah"
}]
}]
}, {
"name": "BlahBloob",
"rubrics": [{
"name": "Bla",
"items": [{
"id": 10000013,
"name": "Gut"
}]
}, {
"name": "Bloob",
"items": [{
"id": 10000014,
"name": "Name"
}, {
"id": 10000015,
"name": "Lorem"
}]
}]
}]
};
var itemObj = {};
var itemArr = [];
var sections = data.sections;
for(var i=0;i<sections.length;i++)
{
for(var j=0;j<sections[i].rubrics.length;j++){
for(var k=0;k<sections[i].rubrics[j].items.length;k++){
var itemObj;
itemObj['id'] = sections[i].rubrics[j].items[k].id;
itemObj['name'] = sections[i].rubrics[j].items[k].name;
itemArr.push(itemObj);
}
}
}
var finalObj = {"items":itemArr};
console.log(finalObj);
JSFiddle

Categories

Resources