Choose Random Item from JSON Response - javascript

I have a JSON response that looks like this:
{
"category1": [
{
"Description": "Insert description here",
"Title": "Title #1"
}
],
"category2": [
{
"Description": "Insert description here",
"Title": "Title #2"
},
{
"Description": "Insert description here",
"Title": "Title #3"
}
]
}
How can I get a random item from this response by reading through both categories?
My JSFiddle here works for Category 2. But I don't know how to read both categories: http://jsfiddle.net/uzpfxdgp/

var mapped = Object.keys(json).map(function(key, index){ return json[key]; })
.reduce(function(a, b) { return a.concat(b); });
var index = Math.floor(Math.random() * mapped.length);
console.log(mapped[index]);

Take a look at this jsFiddle that I created. Is that what you are looking for?
http://jsfiddle.net/Arllo/q66wkkmx/
var list = {
"category1": [
{
"Description": "Insert description here",
"Title": "Title #1"
}
],
"category2": [
{
"Description": "Insert description here",
"Title": "Title #2"
},
{
"Description": "Insert description here",
"Title": "Title #3"
}
]
};
var numberOfProperties = Object.keys(list).length;
var randomProperty = Math.floor((Math.random() * numberOfProperties) + 1);
var randomCategory = "category" + randomProperty;
console.log(list[randomCategory]);

I didn't test this, but I think this might do the trick (where myObj is the object you included above).
var categoryArr = [];
for (var category in myObj) {
categoryArr.push(myObj[category])
}
var randomObj = categoryArr[Math.floor(Math.random() * categoryArr.length)];

Related

How can i get two objects from array using javascript from specific position?

I am trying to get two objects from array using the splice() method. But it is not working as expected. Please guide me where i am wrong or help me to fix this. if anybody can modify this code to a simpler version would be appreciated.
Basically, I am trying to join two objects title and content. So please help me to fix this.
const output = [{
"title": "Lorem Ipsum Test Title 1"
},
{
"content": "The short answer to this is yes."
},
{
"title": "Lorem Ipsum Test Title 2"
},
{
"content": "The short answer to this is yes."
},
{
"title": "Lorem Ipsum Test Title 3"
},
{
"content": "The short answer to this is yes."
},
{
"title": "Lorem Ipsum Test Title 4"
},
{
"content": "The short answer to this is yes."
}
];;
let start = 0;
let end = 2;
const finalOutput = [];
for (j = 0; j <= output.length; j++) {
const data = output.splice(start, end);
if (typeof data[0] != 'undefined') {
finalOutput.push({
title: data[0].title,
content: data[1].content
});
}
start = start + 2;
end = end + 2;
}
console.log(finalOutput)
The final output from the above code is below. It skips two objects.
You have an issue in that output.length changes during your iteration, and you are splicing from increasing indexes, although because you have spliced the array has shortened. If you want to keep using splice, change your code as follows:
const output = [{
"title": "Lorem Ipsum Test Title"
},
{
"content": "The short answer to this is yes."
},
{
"title": "Lorem Ipsum Test Title #2"
},
{
"content": "The short answer to this is also yes."
},
{
"title": "Lorem Ipsum Test Title #3"
},
{
"content": "The short answer to this is not yes."
}
];
const finalOutput = [];
const len = output.length;
for (j = 0; j < len; j+=2) {
const data = output.splice(0, 2);
finalOutput.push({
title: data[0].title,
content: data[1].content
});
}
console.log(finalOutput)
Alternatively, use slice and the code might be more logical:
const output = [{
"title": "Lorem Ipsum Test Title"
},
{
"content": "The short answer to this is yes."
},
{
"title": "Lorem Ipsum Test Title #2"
},
{
"content": "The short answer to this is also yes."
},
{
"title": "Lorem Ipsum Test Title #3"
},
{
"content": "The short answer to this is not yes."
}
];
const finalOutput = [];
for (j = 0; j < output.length; j+=2) {
const data = output.slice(j, j+2);
finalOutput.push({
title: data[0].title,
content: data[1].content
});
}
console.log(finalOutput)
Note in both cases start and end are redundant and you don't need the check on data[0] as it is guaranteed to be valid.
Or you can think about a method with more functional
const output = [{
"title": "Title 1"
},
{
"content": "Content 1"
},
{
"title": "Title 2"
},
{
"content": "Content 2"
},
{
"title": "Title 3"
},
{
"content": "Content 3"
}];
const reducer = (pre, cur) => {
if (cur.content) {
pre[pre.length - 1].content = cur.content;
return pre;
}
return [...pre, {
title: cur.title
}]
}
const join = output.reduce(reducer, [])
console.log(join) // [{"title":"Title 1","content":"Content 1"},{"title":"Title 2","content":"Content 2"},{"title":"Title 3","content":"Content 3"}]
I think Ghost has the best answer - neat and simple.
I had something along those lines but not as neat:
output.map((value, index, array) => {
if (index == 0 || index % 2 == 0){
const contentIndex = index + 1;
return { "title": value.title, "content": array[contentIndex].content }
}
}).filter(o => o !== undefined);
//easiest way to do is
<script>
let value=[]
const output = [
{
"title": "Lorem Ipsum Test Title"
},
{
"content": "The short answer to this is yes."
},
{
"title": "Lorem Ipsum Test Title"
},
{
"content": "The short answer to this is yes."
},
{
"title": "Lorem Ipsum Test Title"
},
{
"content": "The short answer to this is yes."
}
];
for(let i=0;i<output.length;){
value.push({...output[i],...output[i+1]})
i+=2;
}
console.log(value)
</script>

get previous json item in Json

I have a JSON file titled stuff.json. I am trying to get the previous json item given a certain item. For example, if I am given the key ["also-random-here"], how do I get the previous JSON item "sample-name"?
My JSON data looks as follows:
{
"random-name-here": {
"name": "name is item1"
},
"sample-name": {
"name": "name is item2"
},
"also-random-here": {
"name": "name is item3"
}
}
try this
var names={
"random-name-here": {
"name": "name is item1"
},
"sample-name": {
"name": "name is item2"
},
"also-random-here": {
"name": "name is item3"
}
};
var prevName= findPrevName(names, "also-random-here") ;
function findPrevName(item, key) {
var prevName;
for (const property in item)
{
if(property==key) break;
prevName=property;
};
return { [prevName]: item[prevName]};
};

Restructuring an object with map and forEach

I've got an object that i'm trying to map to a react component (using lodash). The current shape of the objects that I get back from my API (firebase) looks like this...
// ex. 1
{
"-Kdkahgiencls0dnh": {
"name": "a name",
"desc": "a description",
"other": "some other guff"
},
"-Ksdfadfvcls0dsnh": {
"name": "another name",
"desc": "another description",
"other": "some more"
},
"-kgoandiencls0dnh": {
"name": "I am a name",
"desc": "I am a description",
"other": "I am some other guff"
}
}
...but, I loose the primary key when i run through _.map()
What i'm trying to do is get my object in the shape of:
// ex. 2
[
{
"id": "-Kdkahgiencls0dnh",
"name": "a name",
"desc": "a description",
"other": "some other guff"
},
{... the next object ...},
{... etc ...}
]
What i'm doing now is getting my data in the componentWillMount lifecycle method like so:
componentWillMount() {
firebaseRef.on('value', snap => {
let data = snap.val() // the whole original object (see ex. 1)
let tempArray = [] // an array to store my newly formatted objects
_.forEach(data, (item, key) => {
// Here's where i'm not really sure what to do.
// I want to use Object.assign to set a new key:value
// That adds "id": "-theobjectsmainkey" to a new object
// then push to my tempArray and finally setState with the
// correctly formatted array of objects.
})
})
}
Ideas? Thoughts? Thanks.
You can use Object.entries(), .map() and object spread
const data = {
"-Kdkahgiencls0dnh": {
"name": "a name",
"desc": "a description",
"other": "some other guff"
},
"-Ksdfadfvcls0dsnh": {
"name": "another name",
"desc": "another description",
"other": "some more"
},
"-kgoandiencls0dnh": {
"name": "I am a name",
"desc": "I am a description",
"other": "I am some other guff"
}
}
let res = Object.entries(data).map(([id, prop]) => ({id, ...prop}));
console.log(res);
Lodash's _.map() callback receives as a 2nd parameter the iterated key. Use object assign, to create a new object with the key as id:
const array = _.map(data, (item, id) => Object.assign({ id }, item))
Demo:
const data = {"-Kdkahgiencls0dnh":{"name":"a name","desc":"a description","other":"some other guff"},"-Ksdfadfvcls0dsnh":{"name":"another name","desc":"another description","other":"some more"},"-kgoandiencls0dnh":{"name":"I am a name","desc":"I am a description","other":"I am some other guff"}};
const array = _.map(data, (item, id) => Object.assign({ id }, item));
console.log(array);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
Here you go, using only pure JS :
const raw = {
"-Kdkahgiencls0dnh": {
"name": "a name",
"desc": "a description",
"other": "some other guff"
},
"-Ksdfadfvcls0dsnh": {
"name": "another name",
"desc": "another description",
"other": "some more"
},
"-kgoandiencls0dnh": {
"name": "I am a name",
"desc": "I am a description",
"other": "I am some other guff"
}
}
let formatted = Object.keys(raw).map(
key=>Object.assign(raw[key], {"id": ""+key})
);
Here is a fiddle to get a live demo.
componentWillMount() {
firebaseRef.on('value', snap => {
let data = snap.val() // the whole original object (see ex. 1)
let tempArray = Object.keys(data).map((item, key) => {
return {
"id": item,
"name": data[item].name // etc, a structure what you want
...
};
})
})
}

Javascript merge 2 arrays into a 3rd array to get all data required

I have 2 separate arrays which I need to merge into a third one so I can get all the data required.
Basically the 1st array has an id, and name and in order to get the address I need to search inside the 2nd array and match the id's so I can have all the data from the person.
Here is the data and code:
//Array 1
var myPeopleArray = [{"people":[{"id":"123","name":"name 1"},{"id":"456","name":"name 2"}]}];
//Array 2
var myPersonArray = [{"person":[{"id":"123","address":"address 1"},{"id":"456","address":"address 2"}]}];
var arrayLength = myPeopleArray[0].people.length;
for (var i = 0; i < arrayLength; i++) {
console.log("id: " + myPeopleArray[0].people[i].id);
}
//Wanted Result:
[{"people":[
{
"id":"123",
"name":"name 1",
"address":"address 1"
},
{
"id":"456",
"name":"name 2",
"address":"address 2"
}
]
}]
How can I do this?
var myPeopleArray = [{"people":[{"id":"123","name":"name 1"}, {"id":"456","name":"name 2"}]}];
var myPersonArray = [{"person":[{"id":"123","address":"address 1"}, {"id":"456","address":"address 2"}]}];
for(var i=0;i<myPeopleArray[0].people.length;i++)
{
myPeopleArray[0].people[i].address = myPersonArray[0].person[i].address;
}
document.write(JSON.stringify(myPeopleArray));
You could iterate both arrays and build new object with the joined properties.
var myPeopleArray = [{ "people": [{ "id": "123", "name": "name 1" }, { "id": "456", "name": "name 2" }] }],
myPersonArray = [{ "person": [{ "id": "123", "address": "address 1" }, { "id": "456", "address": "address 2" }] }],
hash = Object.create(null),
joined = [],
joinById = function (o) {
if (!(o.id in hash)) {
hash[o.id] = {};
joined.push(hash[o.id]);
}
Object.keys(o).forEach(function (k) {
hash[o.id][k] = o[k];
});
};
myPeopleArray[0].people.forEach(joinById);
myPersonArray[0].person.forEach(joinById);
console.log(joined);

How to get json values for a key using javascript or jquery or angularjs?

I have the following json:
var jsonobj = {
"title" : "Testing",
"settings" : {
"mysettings" : false
},
"jsonlist": ["TestingList"],
"testjsonvals": {
"Test1": {
"name": "name1",
"description": "Test1 description"
},
"Test2": {
"name": "name2",
"description": "Test2 description"
},
"Test3": {
"name": "name3",
"description": "Test3 description"
}
}
}
How can I get/show description values of Test1, Test2, Test3 only from my given json on one alert message(like: Test1 description, Test2 description, Test3 description should show on my alert message) either using javascript or jquery or angularjs ? Please help me and Thanks in advance.
you should iterate jsonobj["testjsonvals"] (or jsonobj.testjsonvals) object keys and concatenate description values, or push them into array and join()
var jsonobj = {
"title" : "Testing",
"settings" : {
"mysettings" : false
},
"jsonlist": ["TestingList"],
"testjsonvals": {
"Test1": {
"name": "name1",
"description": "Test1 description"
},
"Test2": {
"name": "name2",
"description": "Test2 description"
},
"Test3": {
"name": "name3",
"description": "Test3 description"
}
}
}
var msg = [];
$.each(jsonobj["testjsonvals"], function(key,v){ msg.push(v["description"]) });
alert(msg.join(", "));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
you can do like this
var tests=jsonobj['testjsonvals'];
alert(tests["Test1"]['description'])
var message = jsonobj.testjsonvals.Test1.description + ', ' +
jsonobj.testjsonvals.Test2.description + ', ' +
jsonobj.testjsonvals.Test3.description;
alert(message);
alert( jsonobj ['testjsonvals'['Test1'].description, +
jsonobj ['testjsonvals'] ['Test2'].description, +
jsonobj ['testjsonvals']['Test3'].description );
or
alert( jsonobj.testjsonvals.Test1.description, +
jsonobj.testjsonvals.Test2.description, +
jsonobj.testjsonvals.Test3.description );
Let me know if this code helped you
This will loop over all your testjsonvals and add them to an array that we join together with space and alert
var arr = [];
for(i in jsonobj.testjsonvals)
{
arr.push(jsonobj.testjsonvals[i].description);
}
alert(arr.join(" "));
If you iterate through jsonobj.testjsonvals you should be able to build up your string to match what you require. Something like this should do the trick:
var jsonobj = {
"title" : "Testing",
"settings" : {
"mysettings" : false
},
"jsonlist": ["TestingList"],
"testjsonvals": {
"Test1": {
"name": "name1",
"description": "Test1 description"
},
"Test2": {
"name": "name2",
"description": "Test2 description"
},
"Test3": {
"name": "name3",
"description": "Test3 description"
}
}
};
var tests = jsonobj.testjsonvals;
var msg = [];
for (var i in tests) {
if (tests.hasOwnProperty(i)) {
msg.push(tests[i].description);
}
}
alert(msg.join(' '));

Categories

Resources