-
-
Save YagoLopez/1c2fe87d255fc64d5f1bf6a920b67484 to your computer and use it in GitHub Desktop.
/* Attribution: http://techslides.com/how-to-parse-and-search-json-in-javascript */ | |
//return an array of objects according to key, value, or key and value matching | |
function getObjects(obj, key, val) { | |
var objects = []; | |
for (var i in obj) { | |
if (!obj.hasOwnProperty(i)) continue; | |
if (typeof obj[i] == 'object') { | |
objects = objects.concat(getObjects(obj[i], key, val)); | |
} else | |
//if key matches and value matches or if key matches and value is not passed (eliminating the case where key matches but passed value does not) | |
if (i == key && obj[i] == val || i == key && val == '') { // | |
objects.push(obj); | |
} else if (obj[i] == val && key == ''){ | |
//only add if the object is not already in the array | |
if (objects.lastIndexOf(obj) == -1){ | |
objects.push(obj); | |
} | |
} | |
} | |
return objects; | |
} | |
//return an array of values that match on a certain key | |
function getValues(obj, key) { | |
var objects = []; | |
for (var i in obj) { | |
if (!obj.hasOwnProperty(i)) continue; | |
if (typeof obj[i] == 'object') { | |
objects = objects.concat(getValues(obj[i], key)); | |
} else if (i == key) { | |
objects.push(obj[i]); | |
} | |
} | |
return objects; | |
} | |
//return an array of keys that match on a certain value | |
function getKeys(obj, val) { | |
var objects = []; | |
for (var i in obj) { | |
if (!obj.hasOwnProperty(i)) continue; | |
if (typeof obj[i] == 'object') { | |
objects = objects.concat(getKeys(obj[i], val)); | |
} else if (obj[i] == val) { | |
objects.push(i); | |
} | |
} | |
return objects; | |
} | |
var json = '{"glossary":{"title":"example glossary","GlossDiv":{"title":"S","GlossList":{"GlossEntry":{"ID":"SGML","SortAs":"SGML","GlossTerm":"Standard Generalized Markup Language","Acronym":"SGML","Abbrev":"ISO 8879:1986","GlossDef":{"para":"A meta-markup language, used to create markup languages such as DocBook.","ID":"44","str":"SGML","GlossSeeAlso":["GML","XML"]},"GlossSee":"markup"}}}}}'; | |
var js = JSON.parse(json); | |
//example of grabbing objects that match some key and value in JSON | |
console.log(getObjects(js,'ID','SGML')); | |
//returns 1 object where a key names ID has the value SGML | |
//example of grabbing objects that match some key in JSON | |
console.log(getObjects(js,'ID','')); | |
//returns 2 objects since keys with name ID are found in 2 objects | |
//example of grabbing obejcts that match some value in JSON | |
console.log(getObjects(js,'','SGML')); | |
//returns 2 object since 2 obects have keys with the value SGML | |
//example of grabbing objects that match some key in JSON | |
console.log(getObjects(js,'ID','')); | |
//returns 2 objects since keys with name ID are found in 2 objects | |
//example of grabbing values from any key passed in JSON | |
console.log(getValues(js,'ID')); | |
//returns array ["SGML", "44"] | |
//example of grabbing keys by searching via values in JSON | |
console.log(getKeys(js,'SGML')); | |
//returns array ["ID", "SortAs", "Acronym", "str"] |
thanks @YagoLopez. In my testing, path.slice()
needs to stay inside the for
loop to make a clean break from other obj
references to it. will be trying to scratch out an ES6 refactor of this.
Hey guys! May I recommend you take a look at object-scan. Might be very relevant and exciting 😉 Please do take a look at the source code as well!
https://github.com/blackflux/object-scan
Disclaimer: I'm the author
Looks great! Thanks for the information
How would I go about making this match a wildcard for the key value? For example, my data is:
'{"answer0":"Legend of Zelda","answer1":"Final Fantasy","answer2":"Animal Crossing","answer3":"The Witcher","answer4":"Kingdom Hearts","answer5":"The Sims","artist0":"Wu-Tang Clan","artist1":"Pet Shop Boys","team_id":"79369254","edition_id":"35889464","answerCount":"6","artistCount":"2"}'
I just want the answer*
values . . .
@kyds3k With object-scan you would simply do
const objectScan = require('object-scan');
const data = {
answer0: 'Legend of Zelda',
answer1: 'Final Fantasy',
answer2: 'Animal Crossing',
answer3: 'The Witcher',
answer4: 'Kingdom Hearts',
answer5: 'The Sims',
artist0: 'Wu-Tang Clan',
artist1: 'Pet Shop Boys',
team_id: '79369254',
edition_id: '35889464',
answerCount: '6',
artistCount: '2'
};
console.log(objectScan(['answer*'], { rtn: 'value', reverse: false })(data));
/* => [
'Legend of Zelda',
'Final Fantasy',
'Animal Crossing',
'The Witcher',
'Kingdom Hearts',
'The Sims',
'6'
] */
console.log(objectScan(['(^answer\\d+$)'], { rtn: 'value', reverse: false })(data));
/* => [
'Legend of Zelda',
'Final Fantasy',
'Animal Crossing',
'The Witcher',
'Kingdom Hearts',
'The Sims'
] */
Awesome @simlu 👍
@kyds3k With object-scan you would simply do
const objectScan = require('object-scan'); const data = { answer0: 'Legend of Zelda', answer1: 'Final Fantasy', answer2: 'Animal Crossing', answer3: 'The Witcher', answer4: 'Kingdom Hearts', answer5: 'The Sims', artist0: 'Wu-Tang Clan', artist1: 'Pet Shop Boys', team_id: '79369254', edition_id: '35889464', answerCount: '6', artistCount: '2' }; console.log(objectScan(['answer*'], { rtn: 'value', reverse: false })(data)); /* => [ 'Legend of Zelda', 'Final Fantasy', 'Animal Crossing', 'The Witcher', 'Kingdom Hearts', 'The Sims', '6' ] */ console.log(objectScan(['(^answer\\d+$)'], { rtn: 'value', reverse: false })(data)); /* => [ 'Legend of Zelda', 'Final Fantasy', 'Animal Crossing', 'The Witcher', 'Kingdom Hearts', 'The Sims' ] */
hi i want to try search something using your object scan can that search not fixed value on this object
const data = { merah: [ { harga: 30000, sku: 'SKU-123asd-asdasd', stok: '20', ukuran: 'XL', warna: 'Merah', _id: '6069895a0e277a332ca19e49', }, { harga: 30000, sku: 'SKU-123asd-asdasda', stok: '20', ukuran: 'L', warna: 'Merah', _id: '606b6ea7ff4a142508df2a98', }, ], hijau: [ { harga: 30000, sku: 'SKU-123asd-asdasds', stok: '20', ukuran: 'XL', warna: 'Hijau', _id: '606b6ea7ff4a142508df2a98', }, { harga: 30000, sku: 'SKU-123asd-asdasdsa', stok: '20', ukuran: 'L', warna: 'Hijau', _id: '606b6ea7ff4a142508df2a98', }, ], }
the data will not fixed its will be like another color in english or what ever how do i search depend on the first word like "hijau", "merah"
Sure, just use **
as a search needle and filter with filterFn
using value
. It's all in the docs with detailed examples. Let me know if you're struggling
Or are you trying to search on the key? In that case you could just specify the needle as *
? Is that what you're looking for? If you could provide more details with expected output I'd be able to help better
Or are you trying to search on the key? In that case you could just specify the needle as
*
? Is that what you're looking for? If you could provide more details with expected output I'd be able to help better
yeah i try to search at the key so i should use * instead of ** ? ah yeah is it work on ReactJs too ?
@mzcoder-hub I'd really recommend you take a look at the readme here . It details all the basic use cases and it sound like yours is one of them. Your question is not very clear and so I can't answer it. So you have to options:
- go to the readme and figure out what you need to know yourself
- reformulate the question in a way that I can understand (ideally with example results!) and I will do my best to provide a working solution
Thank you, L~
@simlu i have this data https://prnt.sc/115tz4e and the key is not fixed its generate from database, and i want to search keyword example "merah" and i want to retrieve data from array "merah"
Is this what you want?
const objectScan = require('object-scan');
const data = { merah: [{ harga: 30000, sku: 'SKU-123asd-asdasd', stok: '20', ukuran: 'XL', warna: 'Merah', _id: '6069895a0e277a332ca19e49' }, { harga: 30000, sku: 'SKU-123asd-asdasda', stok: '20', ukuran: 'L', warna: 'Merah', _id: '606b6ea7ff4a142508df2a98' }], hijau: [{ harga: 30000, sku: 'SKU-123asd-asdasds', stok: '20', ukuran: 'XL', warna: 'Hijau', _id: '606b6ea7ff4a142508df2a98' }, { harga: 30000, sku: 'SKU-123asd-asdasdsa', stok: '20', ukuran: 'L', warna: 'Hijau', _id: '606b6ea7ff4a142508df2a98' }] };
console.log(objectScan(['*[*]'])(data));
// => [ [ 'hijau', 1 ], [ 'hijau', 0 ], [ 'merah', 1 ], [ 'merah', 0 ] ]
Is this what you want?
const objectScan = require('object-scan'); const data = { merah: [{ harga: 30000, sku: 'SKU-123asd-asdasd', stok: '20', ukuran: 'XL', warna: 'Merah', _id: '6069895a0e277a332ca19e49' }, { harga: 30000, sku: 'SKU-123asd-asdasda', stok: '20', ukuran: 'L', warna: 'Merah', _id: '606b6ea7ff4a142508df2a98' }], hijau: [{ harga: 30000, sku: 'SKU-123asd-asdasds', stok: '20', ukuran: 'XL', warna: 'Hijau', _id: '606b6ea7ff4a142508df2a98' }, { harga: 30000, sku: 'SKU-123asd-asdasdsa', stok: '20', ukuran: 'L', warna: 'Hijau', _id: '606b6ea7ff4a142508df2a98' }] }; console.log(objectScan(['*[*]'])(data)); // => [ [ 'hijau', 1 ], [ 'hijau', 0 ], [ 'merah', 1 ], [ 'merah', 0 ] ]
i want to get data inside of array object
[
{
harga: 30000,
sku: 'SKU-123asd-asdasd',
stok: '20',
ukuran: 'XL',
warna: 'Merah',
_id: '6069895a0e277a332ca19e49',
},
{
harga: 30000,
sku: 'SKU-123asd-asdasda',
stok: '20',
ukuran: 'L',
warna: 'Merah',
_id: '606b6ea7ff4a142508df2a98',
},
],
only single key
if i search 'merah' i only get data from array object from key 'merah'
Still guessing what you want... how about this?
const objectScan = require('object-scan');
const data = { merah: [{ harga: 30000, sku: 'SKU-123asd-asdasd', stok: '20', ukuran: 'XL', warna: 'Merah', _id: '6069895a0e277a332ca19e49' }, { harga: 30000, sku: 'SKU-123asd-asdasda', stok: '20', ukuran: 'L', warna: 'Merah', _id: '606b6ea7ff4a142508df2a98' }], hijau: [{ harga: 30000, sku: 'SKU-123asd-asdasds', stok: '20', ukuran: 'XL', warna: 'Hijau', _id: '606b6ea7ff4a142508df2a98' }, { harga: 30000, sku: 'SKU-123asd-asdasdsa', stok: '20', ukuran: 'L', warna: 'Hijau', _id: '606b6ea7ff4a142508df2a98' }] };
const r = objectScan(['*[*]'], { rtn: 'value' })(data);
console.log(JSON.stringify(r));
// => [{"harga":30000,"sku":"SKU-123asd-asdasdsa","stok":"20","ukuran":"L","warna":"Hijau","_id":"606b6ea7ff4a142508df2a98"},{"harga":30000,"sku":"SKU-123asd-asdasds","stok":"20","ukuran":"XL","warna":"Hijau","_id":"606b6ea7ff4a142508df2a98"},{"harga":30000,"sku":"SKU-123asd-asdasda","stok":"20","ukuran":"L","warna":"Merah","_id":"606b6ea7ff4a142508df2a98"},{"harga":30000,"sku":"SKU-123asd-asdasd","stok":"20","ukuran":"XL","warna":"Merah","_id":"6069895a0e277a332ca19e49"}]
Still guessing what you want... how about this?
const objectScan = require('object-scan'); const data = { merah: [{ harga: 30000, sku: 'SKU-123asd-asdasd', stok: '20', ukuran: 'XL', warna: 'Merah', _id: '6069895a0e277a332ca19e49' }, { harga: 30000, sku: 'SKU-123asd-asdasda', stok: '20', ukuran: 'L', warna: 'Merah', _id: '606b6ea7ff4a142508df2a98' }], hijau: [{ harga: 30000, sku: 'SKU-123asd-asdasds', stok: '20', ukuran: 'XL', warna: 'Hijau', _id: '606b6ea7ff4a142508df2a98' }, { harga: 30000, sku: 'SKU-123asd-asdasdsa', stok: '20', ukuran: 'L', warna: 'Hijau', _id: '606b6ea7ff4a142508df2a98' }] }; const r = objectScan(['*[*]'], { rtn: 'value' })(data); console.log(JSON.stringify(r)); // => [{"harga":30000,"sku":"SKU-123asd-asdasdsa","stok":"20","ukuran":"L","warna":"Hijau","_id":"606b6ea7ff4a142508df2a98"},{"harga":30000,"sku":"SKU-123asd-asdasds","stok":"20","ukuran":"XL","warna":"Hijau","_id":"606b6ea7ff4a142508df2a98"},{"harga":30000,"sku":"SKU-123asd-asdasda","stok":"20","ukuran":"L","warna":"Merah","_id":"606b6ea7ff4a142508df2a98"},{"harga":30000,"sku":"SKU-123asd-asdasd","stok":"20","ukuran":"XL","warna":"Merah","_id":"6069895a0e277a332ca19e49"}]
Im fixing it using the script above
console.log(getObjects(js,'','SGML'));
@YagoLopez Thanks! Exactly what I need and it works great
@YagoLopez Thanks! Exactly what I need and it works great
You´re welcome @androcado. Please consider give a start to the gist if you found it useful. Thanks 👍
You'r welcome @johnclary. Awesome refactor.
Let me just add a suggestion: I would move this sentence
var newPath = path.slice();
before thefor
loop to avoid its execution inside the loop. And using ES6 I'm sure you'll get a much more terse code 👍