This question already has answers here:
Finding matching objects in an array of objects?
(5 answers)
Closed 8 years ago.
Say I have a JSON array containing an bunch of different key/values per each object. I know how to use Javascript to target a specific key/value, but what if I want to search through the entire JSON file to find an item, and then also find a related pair within that same object.
For example, how would I scan the following JSON for "Moby Dick", but then also find the author that is tied to that title?
"store": {
"book": [
{ "category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{ "category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
},
{ "category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
},
{ "category": "fiction",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
}
],
}
}
Assuming this is your object:
var store= {
"book": [
{...}, {...}
]
}
Then you can try to filter it like this:
var foundBooks = store.book.filter(function(book) { return book.title ==="Moby Dick"});
As correctly pointed out for #JLRiche foundBooks is an array. In order to access the first match it will be in the same way we do with all arrays:
var book = foundBooks[0];
You'd have to iterate the list, you can create some custom functions, like so:
function findTitle(title) {
for (var i = 0; i < data.store.book.length; i++) {
if (data.store.book[i].title == title) {
return data.store.book[i];
}
}
}
So you can do:
var book = findTitle("Moby Dick"),
author = book.author;
You would loop through your book objects and find where book.title === "Moby Dick" and then take a look at book.author for that particular object.
Related
This question already has answers here:
What is the correct way to check for string equality in JavaScript?
(11 answers)
Closed 2 years ago.
I am trying to make a filtered array of objects. This is the original array:
const data = [{
"id": "80009841-C",
"name": "Giorgio Armani Code Homme Profumo Parfum",
"slug": "parfum/giorgio-armani/code-homme/giorgio-armani-code-homme-profumo-parfum.html",
"brand": "Giorgio Armani",
"type": "Parfum",
},
{
"id": "80022496-C",
"name": "Issey Miyake L'Eau Majeure D'Issey Eau de Toilette",
"slug": "parfum/issey-miyake/l-eau-majeure-d-issey/issey-miyake-l-eau-majeure-d-issey-eau-de-toilette.html",
"brand": "Issey Miyake",
"type": "Eau de Parfum",
}
]
I want to filter by type, using this code I found:
data.filter((product) => product.type.indexOf("Parfum") >= 0)
But I'm not getting what I want, the function is returning an array with both objects, because both have the word "Parfum" inside their "type" values.
Question How can I get an exact match for the values I'm trying to filter?
If exact match is what you want, then simply do this:
data.filter((product) => product.type === "Parfum");
const data = [{
"id": "80009841-C",
"name": "Giorgio Armani Code Homme Profumo Parfum",
"slug": "parfum/giorgio-armani/code-homme/giorgio-armani-code-homme-profumo-parfum.html",
"brand": "Giorgio Armani",
"type": "Parfum",
},
{
"id": "80022496-C",
"name": "Issey Miyake L'Eau Majeure D'Issey Eau de Toilette",
"slug": "parfum/issey-miyake/l-eau-majeure-d-issey/issey-miyake-l-eau-majeure-d-issey-eau-de-toilette.html",
"brand": "Issey Miyake",
"type": "Eau de Parfum",
}
];
const filtered = data.filter(item => item.type == "Parfum");
console.log(filtered);
I have the below JSON and in each object there is an artist and image values. I want a mechanism that when I give a name of the artist it returns the value of the image in the same object. All objects are warped in an array as a JSON.
var iTunes_data = $([{
"title": "title1",
"image": "images/image1.jpg"
},
{
"title": "Hotel California [Rainwave Chiptunes]",
"image": "images/image2.jpg"
},
{
"title": "The Multi-Story Car Park [Rainwave Chiptunes]",
"image": "images/image3.jpg"
},
{
"title": "title4",
"image": "images/image4.jpg"
},
{
"title": "title5",
"image": "images/image2.jpg"
}
]);
function getImage(currentTitle) {
let url = iTunes_data.filter(element => element.title === currentTitle);
return url[0].image;
}
console.log(getImage("title5"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
So when I ask for title5 I want to get images/image2.jpg.
I do not want to use the any loop. It has to be more by finding the key and getting the value rather than going through the JSON by a loop, as I find this way faster.
Any idea how to make it working?
Thanks in advance
There's no way to not use a loop. If you want to be more efficient you should take an imperative approach with a for loop and break with a match.
for(let obj in data) {
if(obj.title === title)
// match
break
}
Hope this helps.
To get a specific element from an array without looping, you'll have to know its index. The best you could do is to only loop the array once to map each title to the element's index in the array, here is an example:
const arr = [{
"title": "title1",
"image": "images/image1.jpg"
},
{
"title": "Hotel California [Rainwave Chiptunes]",
"image": "images/image2.jpg"
},
{
"title": "The Multi-Story Car Park [Rainwave Chiptunes]",
"image": "images/image3.jpg"
},
{
"title": "title4",
"image": "images/image4.jpg"
},
{
"title": "title5",
"image": "images/image2.jpg"
}]
const map = arr.reduce((a, c, index) => {
a[c.title] = index;
return a;
},{});
function getImage(title) {
if (!isNaN(map[title])) {
return arr[map[title]].image;
}
}
console.log(getImage('title5'));
I've used a normal array instead of a jQuery object in this example.
I'm assuming the array will not change, you'll have to keep the map in sync if you're going to change the array's content.
I am working with facebook JS SDK which returns user's information in JSON format. I know how to get the response like response.email which returns email address. But how to get an element from a nested array object? Example: user's education history may contain multiple arrays and each array will have an element such as "name" of "school". I want to get the element from the last array of an object.
This is a sample JSON I got:-
"education": [
{
"school": {
"id": "162285817180560",
"name": "Jhenaidah** School"
},
"type": "H**hool",
"year": {
"id": "14404**5610606",
"name": "2011"
},
"id": "855**14449421"
},
{
"concentration": [
{
"id": "15158**968",
"name": "Sof**ering"
},
{
"id": "20179020**7859",
"name": "Dig**ty"
}
],
"school": {
"id": "10827**27428",
"name": "Univer**g"
},
"type": "College",
"id": "9885**826013"
},
{
"concentration": [
{
"id": "108196**810",
"name": "Science"
}
],
"school": {
"id": "2772**996993",
"name": "some COLLEGE NAME I WANT TO GET"
},
"type": "College",
"year": {
"id": "1388*****",
"name": "2013"
},
"id": "8811215**16"
}]
Let's say I want to get "name": "some COLLEGE NAME I WANT TO GET" from the last array. How to do that with Javascript? I hope I could explain my problem. Thank you
Here is a JsFiddle Example
var json = '{}' // your data;
// convert to javascript object:
var obj = JSON.parse(json);
// get last item in array:
var last = obj.education[obj.education.length - 1].school.name;
// result: some COLLEGE NAME I WANT TO GET
If your json above was saved to an object called json, you could access the school name "some COLLEGE NAME I WANT TO GET" with the following:
json.education[2].school.name
If you know where that element is, then you can just select it as already mentioned by calling
var obj = FACEBOOK_ACTION;
obj.education[2].school.name
If you want to select specifically the last element, then use something like this:
obj.education[ obj.education.length - 1 ].scool.name
Try this,
if (myData.hasOwnProperty('merchant_id')) {
// do something here
}
where JSON myData is:
{
amount: "10.00",
email: "someone#example.com",
merchant_id: "123",
mobile_no: "9874563210",
order_id: "123456",
passkey: "1234"
}
This is a simple example for your understanding. In your scenario of nested objects, loop over your JSON data and use hasOwnProperty to check if key name exists.
I have a jsonPath as below
{ "book":
[
{ "category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{ "category": "fiction",
"author": "Nigel Rees",
"title": "Sword of Honour",
"price": 12.99
}
]}
And Want to check if any author name have got repeated?
I tried
$.book[?(#.author=='Nigel Rees')].find(1)
But, it always throws an exception that found nothing, how could I check that the author='Nigel Rees' occurrences i.e author='Nigel Rees' have a two books?
Depends what you are planning on doing if the authors names exists.
If you only want the objects with author of Nigel Reese you could use a filter.
var booksByNigelReese = book.filter( function(book, index) {
return book.author === 'Nigel Reese'
})
.filter() takes a function that takes the book and index, chooes to accept or rejcet the book into a new array depending if the result of the function is true or false
I'm a beginner in Javascript so please exuse this probably dumb question. I want to merge two json files based on unique object id.
Number one look like this:
"features": [{
"id": "3876802",
"properties": {
"name": "some name",
"facts": "some facts"}},
{"id": "3876803",
"properties": {"name":"another name"...}}...]
Number Two looks like this:
"features": [{
"id": "3876803",
"properties": {
"description": "some description",
"website": "afancywebsite"}},
{"id": "3876803",
"properties": {...}}]
The Elements in the second Json are not in the same order and not all elements of the first file exist in the second.
The Result should look like this:
"features": [{
"id": "3876802",
"properties": {
"name": "some name",
"facts": "some facts"}},{
"id": "3876803",
"properties": {
"name":"another name",
"description": "some description",
"website": "afancywebsite"}}]
I started coding this but I have no idea how to get it working...
for(var i in json1.features){
for (var z in json2.features){
if (json1.features[i].id===json2.features[z].id){
json1.feature[i].properties = json2.features[z].properties}}}
This will do the job:
var features = [
{"id": "3876802",
"properties": {
"name": "some name",
"facts": "some facts"}
},
{"id": "3876803",
"properties": {
"name":"another name"
}
}
];
var features2 = [{
"id": "3876803",
"properties": {
"description": "some description",
"website": "afancywebsite"
}
}
];
features.map(function(feature){
var matchedArray = features2.filter(function(feature2){
return feature2.id === feature.id;
});
if(matchedArray && matchedArray[0]){
for(var attr in matchedArray[0].properties){
feature.properties[attr] = matchedArray[0].properties[attr];
}
}
});
We start by using Array.map() to run through the 'features' array, one by one.
Then we use Array.filter() on the features2 array which gives us an array containing the only object in features2 (matched[0]) which has the same id as feature.id.
If there's a match, then we run through the 'properties' in the features2 object using a 'for in' loop and copy them to the 'feature' object.
If you want to get advanced info about this check out this stackoverflow question: How can I merge properties of two JavaScript objects dynamically?. For example, if you're writing bullet-proof javascript you should use 'hasOwnProperty' in a for in loop.
You may also want to guard against properties in 'features2' overwriting a property with the same name in 'features'.
However if you would like to keep your code more or less as it was this also works:
for(var i in features){
for (var z in features2){
if (features[i].id===features2[z].id){
for(var attr in features2[z].properties){
features[i].properties[attr] = features2[z].properties[attr];
}
}
}
}