iterate through Json array without having a key - javascript

First of all, this question might have been asked several times already, but every thread I found didn't help me. I would appreciate if one could rewrite my function below.
I have the following array with Json objects.
The goal is to get the "url" values. Right now I get every value from that array.
a = [{
"result": [{
"name": [
"name"
],
"url": [
"www.bar.com"
]
},
{
"name": [
"name 2"
],
"url": [
"www.bar.org"
]
},
{
"name": [
"name 1"
],
"url": [
"www.bar.biz"
]
},
{
"name": [
"name 3"
],
"url": [
"www.bar.jp"
]
}
]
}];
document.getElementById("foo").innerHTML = "How to explicitly get the url value?'";
loopThrough(a);
function loopThrough(obj) {
for (var key in obj) {
// skip loop if the property is from prototype
if (!obj.hasOwnProperty(key)) continue;
if (typeof obj[key] !== 'object') {
console.log(obj[key]);
} else {
loopThrough(obj[key]);
}
}
}
<div id="foo">
</div>
How would I access each "url" element in this array?
Maybe there is also a smarter solution than this.
Thank you in advance.

a = [{
"result": [{
"name": [
"name"
],
"url": [
"www.bar.com"
]
},
{
"name": [
"name 2"
],
"url": [
"www.bar.org"
]
},
{
"name": [
"name 1"
],
"url": [
"www.bar.biz"
]
},
{
"name": [
"name 3"
],
"url": [
"www.bar.jp"
]
}
]
}];
loopThrough(a);
// Uses ES6 syntax
function loopThrough(obj) {
obj[0].result.forEach(r => console.log(r.url[0]));
}

try it yourself.
var a = [{
"result": [{
"name": [
"name"
],
"url": [
"www.bar.com"
]
},
{
"name": [
"name 2"
],
"url": [
"www.bar.org"
]
},
{
"name": [
"name 1"
],
"url": [
"www.bar.biz"
]
},
{
"name": [
"name 3"
],
"url": [
"www.bar.jp"
]
}
]
}];
var urls=a[0].result.reduce(function(urls,it){
return urls.concat(it.url);
},[]);
console.log(urls);

Related

Flattening an array of objects based on specific keys

I am currently making a tree view, where there will be folders and subfolders.
The code is as such from my json file:
[
{
"name": "Knowledge Base",
"files": [
"knowledge-base.pdf",
"hello-word.pdf"
],
"folders": [
{
"name": "Documents",
"files": [
"file1.pdf",
"file2.pdf",
"file3.pdf"
],
"folders": [
{
"name": "Important Documents",
"files": [
"I like trains",
"Why",
"OMG NOOOO"
],
"folders": [
{
"name": "Hello World",
"files": [
"Hell no"
]
}
]
},
{
"name": "My secrets",
"files": [
"Pay",
"I dont like my boss",
"Hobbies"
]
}
]
},
{
"name": "Images",
"files": [
"image1.png",
"image2.png",
"image3.png",
"image4.png",
"image5.png"
],
"folders": ""
},
{
"name": "Important",
"files": [
"confidential.pdf",
"important.pdf"
],
"folders": ""
}
]
},
{
"name": "Downloads",
"files": [
"download1.pdf",
"download2.pdf",
"download3.pdf"
],
"folders": ""
},
{
"name": "Favourites",
"files": [
"favourite1.pdf",
"favourite2.pdf",
"favourite3.pdf",
"favourite4.pdf"
],
"folders": ""
}
]
A new folder is denoted with a new object {}, which consists of its name, files and folders within it, if any.
I would like to flatten the dictionary such that it outputs all files (with a file is denoted by a . and a folder is denoted by a >:
For example, for the documents folder:
Knowledge Base>Documents.file1.pdf
Knowledge Base>Documents.file2.pdf
Knowledge Base>Documents.file3.pdf
Knowledge Base>Documents>Important Documents.I like trains
Knowledge Base>Documents>Important Documents.Why
Knowledge Base>Documents>Important Documents.OMG NOOOO
Knowledge Base>Documents>Important Documents>Hello World.Hell no
Knowledge Base>Documents>My Secrets.I dont like my boss
Knowledge Base>Documents>My Secrets.Hobbies
You can use a basic recusrive function like this:
const tree = [{
"name": "Knowledge Base",
"files": [
"knowledge-base.pdf",
"hello-word.pdf"
],
"folders": [{
"name": "Documents",
"files": [
"file1.pdf",
"file2.pdf",
"file3.pdf"
],
"folders": [{
"name": "Important Documents",
"files": [
"I like trains",
"Why",
"OMG NOOOO"
],
"folders": [{
"name": "Hello World",
"files": [
"Hell no"
]
}]
},
{
"name": "My secrets",
"files": [
"Pay",
"I dont like my boss",
"Hobbies"
]
}
]
},
{
"name": "Images",
"files": [
"image1.png",
"image2.png",
"image3.png",
"image4.png",
"image5.png"
],
"folders": ""
},
{
"name": "Important",
"files": [
"confidential.pdf",
"important.pdf"
],
"folders": ""
}
]
},
{
"name": "Downloads",
"files": [
"download1.pdf",
"download2.pdf",
"download3.pdf"
],
"folders": ""
},
{
"name": "Favourites",
"files": [
"favourite1.pdf",
"favourite2.pdf",
"favourite3.pdf",
"favourite4.pdf"
],
"folders": ""
}
]
var result = []
function rec(folders, acc) {
if (folders) {
folders.forEach(folder => {
const newAcc = !!acc ? `${acc}>${folder.name}` : `${folder.name}`
if (folder.files) {
const newFiles = folder.files.map(file => `${newAcc}.${file}`)
result = [...result, ...newFiles]
}
if (folder.folders) {
rec(folder.folders, newAcc)
}
})
}
}
rec(tree, '')
console.log(result)
For that you need to do a recursive identifying when it is an array, a folder or a file.
const treeView = [
{
name: "Knowledge Base",
files: [
"knowledge-base.pdf",
"hello-word.pdf"
],
folders: [
{
name: "Documents",
files: [
"file1.pdf",
"file2.pdf",
"file3.pdf"
],
folders: [
{
name: "Important Documents",
files: [
"I like trains",
"Why",
"OMG NOOOO"
],
folders: [
{
name: "Hello World",
files: [
"Hell no"
]
}
]
},
{
name: "My secrets",
files: [
"Pay",
"I dont like my boss",
"Hobbies"
]
}
]
},
{
name: "Images",
files: [
"image1.png",
"image2.png",
"image3.png",
"image4.png",
"image5.png"
],
folders: ""
},
{
name: "Important",
files: [
"confidential.pdf",
"important.pdf"
],
folders: ""
}
]
},
{
name: "Downloads",
files: [
"download1.pdf",
"download2.pdf",
"download3.pdf"
],
folders: ""
},
{
name: "Favourites",
files: [
"favourite1.pdf",
"favourite2.pdf",
"favourite3.pdf",
"favourite4.pdf"
],
folders: ""
}
]
function handleObj(obj, type, path = '') {
const result = []
if (Array.isArray(obj)) { // recursive on arrays
for (const thisObj of obj) {
result.push(handleObj(thisObj, type, path))
}
} else {
type = type || getType(obj)
if (type === 'folder') { // recursive on folders
const {
name,
files,
folders
} = obj
path = path ? `${path}>${name}` : name
if (files && files.length) {
result.push(handleObj(files, 'file', path))
}
if (folders && folders.length) {
result.push(handleObj(folders, 'folder', path))
}
} else if (type === 'file') {
const filename = obj
if (path) {
result.push(`${path}.${filename}`)
} else {
result.push(`${filename}`)
}
}
}
return result.join('\n')
}
function getType(obj) {
const {
name,
files,
folders
} = obj
if (name !== undefined && files !== undefined && folders !== undefined) {
return 'folder'
}
return 'file'
}
console.log(handleObj(treeView))
Recursive function is to the resqueue.
The idea behind recursive function is that it accepts an object as parameter and if a child of that object contains folders, loop through array of these folders and send each folder object back to the same function.
const data = [
{
"name": "Knowledge Base",
"files": [
"knowledge-base.pdf",
"hello-word.pdf"
],
"folders": [
{
"name": "Documents",
"files": [
"file1.pdf",
"file2.pdf",
"file3.pdf"
],
"folders": [
{
"name": "Important Documents",
"files": [
"I like trains",
"Why",
"OMG NOOOO"
],
"folders": [
{
"name": "Hello World",
"files": [
"Hell no"
]
}
]
},
{
"name": "My secrets",
"files": [
"Pay",
"I dont like my boss",
"Hobbies"
]
}
]
},
{
"name": "Images",
"files": [
"image1.png",
"image2.png",
"image3.png",
"image4.png",
"image5.png"
],
"folders": ""
},
{
"name": "Important",
"files": [
"confidential.pdf",
"important.pdf"
],
"folders": ""
}
]
},
{
"name": "Downloads",
"files": [
"download1.pdf",
"download2.pdf",
"download3.pdf"
],
"folders": ""
},
{
"name": "Favourites",
"files": [
"favourite1.pdf",
"favourite2.pdf",
"favourite3.pdf",
"favourite4.pdf"
],
"folders": ""
}
];
function flatten(obj, parent = "")
{
parent += obj.name; //append current folder name
let result = obj.files ? obj.files.map(file => parent + "." + file) : [];//add files
if (Array.isArray(obj.folders))
result = result.concat(...obj.folders.map(folder => flatten(folder, parent + ">"))); //recursivly call flatten for next subfolder
return result;
}
const dataFlat = data.reduce((a,b) => (a.push(...flatten(b)), a), []);
console.log(dataFlat);
.as-console-wrapper{top:0;max-height:unset!important;overflow:auto!important;}

javascript print nested array to screen

I have a data array, there are multiple objects in this array, and the data object is an array. There may be more than one object in this array. How can I copy these objects under a single array?
const test = []
const data = [
{
"_id": "124141",
"name": "test",
"data": [
{
"price":10,
"title": "sda"
},
]
},
{
"_id": "2525",
"name": "test2",
"data": [
{
"price":20,
"title": "asdas"
},
]
}
]
[{
"price":10,
"title": "sda"
},
{
"price":20,
"title": "asdas"
},
]
If this is the output I expect, it should be like this. how can I do that
const data = [
{
"_id": "124141",
"name": "test",
"data": [
{
"price":10,
"title": "sda"
},
{
"price":99,
"title":"aaaaa"
}
]
},
{
"_id": "2525",
"name": "test2",
"data": [
{
"price":20,
"title": "asdas"
},
]
}
];
console.log(data.map(e => e.data).flat());
// OR
console.log(data.flatMap(e => e.data));

Filter and get data from JSON

How to get the data value from the list, the size of the array, the main thing is not through the index, because the order of the arrays can change and I can get specific data from the code === "size". Unfortunately, the structure cannot be changed. It came to mind only through the filter, by index, but it is impossible
The result should be 100 150
https://jsoneditoronline.org/#left=cloud.b10638604c214b189f87747414e06035
[
[
"color",
{
"name": "Цвет",
"code": "color",
"list": [
{
"value": "Зеленый"
},
{
"value": "Красный"
}
]
}
],
[
"size",
{
"name": "Размер",
"code": "size",
"list": [
{
"value": "100"
},
{
"value": "150"
}
]
}
]
]
This data structure is terrible, but a quick fix could be something like this
const data = [
[
"color",
{
"name": "Цвет",
"code": "color",
"list": [
{
"value": "Зеленый"
},
{
"value": "Красный"
}
]
}
],
[
"size",
{
"name": "Размер",
"code": "size",
"list": [
{
"value": "100"
},
{
"value": "150"
}
]
}
]
]
const size = data.filter(element => element[1].code === 'size')[0][1].list.map(element => element.value)
console.log(size)

Restructuring JSON in JavaScript

I have this JSON which I'm parsing using NodeJS and it needs to be restructured into the second JSON which I've added below.
In the first JSON, the rows object has two pages objects (any number of pages objects can be present) which contains all the same keys and values with the exception of values and display keys.
{
"pages": [
{
"label": "SomeLabel",
"name": "Some",
"sections": [
{
"type": "Repeat",
"label": "Label 1",
"name": "Name 1",
"rows": [
{
"pages": [
{
"label": "Label 1",
"name": "Name 1",
"sections": [
{
"type": "Flow",
"label": "Label 2",
"name": "Name 2",
"answers": [
{
"label": "Question Label",
"question": "Question",
"values": [
"Value A"
],
"valuesMetadata": [
{
"display": "Display A",
"row": {
"columns": []
}
}
]
}
]
}
]
}
]
},
{
"pages": [
{
"label": "Label 1",
"name": "Name 1",
"sections": [
{
"type": "Flow",
"label": "Label 2",
"name": "Name 2",
"answers": [
{
"label": "Question Label",
"question": "Question",
"values": [
"Value B"
],
"valuesMetadata": [
{
"display": "Display B",
"row": {
"columns": []
}
}
]
}
]
}
]
}
]
}
],
"footer": null
}
]
}
]
}
In the second JSON the rows object has a single pages object, inside of which the values and display keys have multiple values (the non-common values).
{
"pages": [
{
"label": "SomeLabel",
"name": "Some",
"sections": [
{
"type": "Repeat",
"label": "Label 1",
"name": "Name 1",
"rows": [
{
"pages": [
{
"label": "Label 1",
"name": "Name 1",
"sections": [
{
"type": "Flow",
"label": "Label 2",
"name": "Name 2",
"answers": [
{
"label": "Question Label",
"question": "Question",
"values": [
"Value A",
"Value B"
],
"valuesMetadata": [
{
"display": [
"Display A",
"Display B"
],
"row": {
"columns": []
}
}
]
}
]
}
]
}
]
}
],
"footer": null
}
]
}
]
}
So, I want to know the fast and easy steps to do this. Please let me know the process and methods to solve this.
Thanks
If I understand you correctly, you want to combine all pages in a single page that holds all information.
This can be achieved using the Array.reduce function. reduce takes an array and combines all elements to a single value using a function (provided by you) to combine the first two elements until only one is left (i.e. 1 * 2 => new1; new1 * 3 => new2 where * represents your function).
Your problem would look something like this:
rows[0].pages = rows[0].pages.reduce((currentElement, currentState) => {
if (!currentState) { // first iteration return first element but make sure display is an array
currentElement.sections[0].answers[0].valuesMetadata[0].display =
[currentElement.sections[0].answers[0].valuesMetadata[0].display];
return currentElement;
}
// add values of current element to arrays in current state
currentState.sections[0].answers[0].values
.concat(currentElement.sections[0].answers[0].values);
currentState.sections[0].answers[0].valuesMetadata[0].display
.concat(currentElement.sections[0].answers[0].valuesMetadata[0].display);
return currentState;
});
currentElement is the object of the array that is currently reduced, currentState is the intermediate result of the reduction.
PS:
The object looks like you are way too many arrays where you would not need them. The given code snippet works only for the first element in each array (hence the [0]s. If you really do have multiple values in each array you would have to iterate over all of those accordingly.

get records doing a match between arrays rethinkdb

I want get the id from table records that have the array match with other record from the same table's array example:
it is record of user '1'
✔ r.db('fotogena').table('users').filter({user:'1'}).pluck('pleasures')
{
"pleasures": [
{
"category": "432f1ae0-a7b1-11e7-86dc-d709d79803e4",
"subCategory": [
"432f1ae1-a7b1-11e7-86dc-d709d79803e4"
]
},
{
"category": "432f1aef-a7b1-11e7-86dc-d709d79803e4",
"subCategory": [
"432f1af5-a7b1-11e7-86dc-d709d79803e4"
]
},
{
"category": "432f1afa-a7b1-11e7-86dc-d709d79803e4",
"subCategory": [
"432f1afb-a7b1-11e7-86dc-d709d79803e4",
"432f1afc-a7b1-11e7-86dc-d709d79803e4",
"432f1afd-a7b1-11e7-86dc-d709d79803e4"
]
},
{
"category": "432f1b02-a7b1-11e7-86dc-d709d79803e4",
"subCategory": [
"432f1b03-a7b1-11e7-86dc-d709d79803e4",
"432f1b04-a7b1-11e7-86dc-d709d79803e4",
"432f1b07-a7b1-11e7-86dc-d709d79803e4"
]
}
]
}
and i want compare each one that items(without the user '1') inside that pleasure.subCategory with others records inside the same table with the same estructure.
Table with 3 records
[
{
"date": "2017-10-03T03:58:02.651Z",
"id": "d82279a7-fbc6-40a2-99ca-39796ea57efa",
"pleasures": [
{
"category": "432f1ae0-a7b1-11e7-86dc-d709d79803e4",
"subCategory": [
"432f1ae1-a7b1-11e7-86dc-d709d79803e4"
]
},
{
"category": "432f1aef-a7b1-11e7-86dc-d709d79803e4",
"subCategory": [
"432f1af5-a7b1-11e7-86dc-d709d79803e4"
]
},
{
"category": "432f1afa-a7b1-11e7-86dc-d709d79803e4",
"subCategory": [
"432f1afb-a7b1-11e7-86dc-d709d79803e4",
]
},
{
"category": "432f1b02-a7b1-11e7-86dc-d709d79803e4",
"subCategory": [
"432f1b03-a7b1-11e7-86dc-d709d79803e4",
]
}
],
"user": "1"
},
{
"date": "2017-10-07T02:59:45.942Z",
"id": "174c0e35-da79-4ca8-b237-8ec569cc27b1",
"pleasures": [
{
"category": "432f1ae0-a7b1-11e7-86dc-d709d79803e4",
"subCategory": [
"432f1ae1-a7b1-11e7-86dc-d709d79803e4",
]
},
{
"category": "432f1aef-a7b1-11e7-86dc-d709d79803e4",
"subCategory": [
"432f1af3-a7b1-11e7-86dc-d709d79803e4",
"432f1af4-a7b1-11e7-86dc-d709d79803e4"
]
},
{
"category": "432f1afa-a7b1-11e7-86dc-d709d79803e4",
"subCategory": [
"432f1aff-a7b1-11e7-86dc-d709d79803e4",
]
},
{
"category": "432f1b02-a7b1-11e7-86dc-d709d79803e4",
"subCategory": [
"432f1b04-a7b1-11e7-86dc-d709d79803e4",
]
}
],
"user": "10"
},
{
"date": "2017-10-07T02:07:13.715Z",
"id": "dd11edac-e0f5-43ac-811a-eaa78a6509c7",
"pleasures": [
{
"category": "432f1ae0-a7b1-11e7-86dc-d709d79803e4",
"subCategory": [
"432f1ae1-a7b1-11e7-86dc-d709d79803e5"
]
},
{
"category": "432f1aef-a7b1-11e7-86dc-d709d79803e4",
"subCategory": [
"432f1af3-a7b1-11e7-86dc-d709d79803e5"
]
},
{
"category": "432f1afa-a7b1-11e7-86dc-d709d79803e4",
"subCategory": [
"432f1af3-a7b1-11e7-86dc-d709d79803e6"
]
},
{
"category": "432f1b02-a7b1-11e7-86dc-d709d79803e4",
"subCategory": [
"432f1af3-a7b1-11e7-86dc-d709d79803e7"
]
}
],
"user": "25"
}
]
i think that maybe can be it:
r.db('fotogena').table('users').filter({user:'1'}).pluck('pleasures').map(pleasures=>{
return //do something
})
i could solve it, later of search and search, i could created a script that show that i want get
I had that do in unique query(no joins) compare arrays with arrays using .contains() and worked very good
r.db('fotogena').table('users').filter(users=>{
return users('pleasures').contains(category=>{
return category('subCategory').contains(subCategory=>{
return r.db('fotogena').table('users').filter({user: '1'}).pluck('pleasures').contains(pleasures2=>{
return pleasures2('pleasures').contains(subCate2=>{
return subCate2('subCategory')
.contains(subCategory2=>{
return subCategory2.eq(subCategory)
})
})
})
})
}).and(users('user').ne('1'))
})

Categories

Resources