- JSON-FIND
- API
- Instantiation
- #.checkKey(Object, String) -> JSON or False
- #.findValues(Object, . String) -> Object
- #.extractPaths([. String] or False, . [. String]) -> Object
- JSON Find in JavaScript
- Putting in an ID-to-Index Map
- Brute Force Search (corrected)
- Javascript search inside a JSON object
- To find match element in array json.file and change it [node js]
- Find object by property in JSON array
- How can I get the index from a JSON object with value?
- Array.find
- How to use array .filter() to search key value in JSON array of objects
- How to find value in json
- Find the highest number in a json object with javascript and a corresponding index or another value
- Search through a JSON object using JavaScript
- Top comments (13)
JSON-FIND
The goal of the module is provide easy access to JSON or JSON-compatible* values. This is not intended for complex JSON queries, but rather for retrieving specifc values without the need to constantly reference a file’s structure. In other words, if you are treating JSON as a database and making multiple queries on the same file, this is not for you. However, if you need to get information from JSON data such as from reasonably consistent web API calls where the structure of the data can undergo subtle structural changes, then this module aims to provide a convenient way to access that data.
*a JSON-compatible object means the contents of the object can only be:
- Booleans
- Numbers
- Strings
- Objects (of valid JSON)
- Arrays (of valid JSON)
API
Instantiation
/* CommonJS */ const JsonFind = require("json-find"); /* ES6 */ import JsonFind from "json-find"; const test = a: 1, b: 2, c: [ 3, 4, d: e: 5, >, f: e: 8, >, >, ], d: 7, >; const doc = JsonFind(test);
If passed invalid JSON, JsonData will throw an error. If passed a Number/String/Boolean/null, JsonData will simply return the given argument.
#.checkKey(Object, String) -> JSON or False
Performs a depth-first search for the given key and returns its value, otherwise false.
doc.checkKey("g"); // false doc.checkKey("e"); // 5 doc.checkKey("f"); //
#.findValues(Object, . String) -> Object
Searches the given Object for each key given. If a given key exists in the Object, its key/value pair are copied to the resulting Object. If none are matched, an empty Object is returned.
If given an Object with multiple identical keys, the value of the first matching key found will be returned, ignoring the others. However, if identical keys exist on the same level within an Object, the value of the last key will be returned.
doc.findValues("z"); // <> doc.findValues("z", "d"); // < "d": < "e": 5 >> doc.findValues("a", "d"); // < "a": 1, "d": < "e": 5 >> // a.c[2].d.e has already been retrieved, // so the value of the first matching key encountered // by the search for "e" is 8 doc.findValues("d", "e"); // < "d": < "e": 5 >, "e": 8 >
#.extractPaths([. String] or False, . [. String]) -> Object
Extracts the values from JSON at given paths and returns a new Object with values at the given keys. A Path is an Array-of-String|Number, consisting of all keys (including Array indexes) from a root key to the key for the desired value.
The first parameter is an Array of new keys names. If no new names are necessary, false maybe be passed instead.
After the new keys parameter, an arbitrary number of Paths maybe passed. If no new keys are passed, the keys for the returned Object will be the last item in each Path. If there are more Paths than keys, the original keys are used assigned to values without a new key. If there are more new keys than Paths, null is assigned to the extra new keys. If the same key is reused, the key is renamed key + index.
const test = c: 1, b: [ c: 2, d: 4, e: "two" >, c: 3, d: 6 >, c: 4, d: 8, e: "four" >, c: 5, d: 10 >, ], f: "six", g: h: "eight", i: [ j: "ten" >], >, >; const doc = JsonFind(test); doc.extractPaths(false, ["b", 3, "c"]); // doc.extractPaths( ["f is", "h is", "j is"], // new keys to be assigned ["f"], // paths given ["g", "h"], ["g", "i", 0, "j"] ); // /* more Paths than keys */ doc.extractPaths(["a", "b"], ["b", 0, "c"], ["b", 1, "c"], ["b", 2, "c"]); // /* same key reused */ doc.extractPaths(false, ["b", 0, "c"], ["b", 1, "c"], ["b", 2, "c"]); // /* more keys than Paths */ doc.extractPaths(["a", "b", "c"], ["f"], ["g", "i"]); // < a: 'six', b: < h: 'eight', i: [< j: 'ten' >] >, c: null > /* accessing all items in an Array */ doc.b.map((obj, index) => doc.extractPaths(["c is"], ["b", index, "c"])); // [< 'c is': 2 >, < 'c is': 3 >, < 'c is': 4 >, < 'c is': 5 >]
JSON Find in JavaScript
If you’re in control of the generation of this thing, does it have to be an array? Because if not, there’s a much simpler way.
Say this is your original data:
Could you do the following instead?
Then finding the relevant entry by ID is trivial:
id = "one"; // Or whatever
var entry = objJsonResp[id];
objJsonResp[id] = /* New value */;
This takes advantage of the fact that in JavaScript, you can index into an object using a property name as a string — and that string can be a literal, or it can come from a variable as with id above.
Putting in an ID-to-Index Map
(Dumb idea, predates the above. Kept for historical reasons.)
It looks like you need this to be an array, in which case there isn’t really a better way than searching through the array unless you want to put a map on it, which you could do if you have control of the generation of the object. E.g., say you have this originally:
The generating code could provide an id-to-index map:
"index": "one": 0, "two": 1, "three": 2
>,
"data": [
,
,
]
>
Then getting an entry for the id in the variable id is trivial:
var index = objJsonResp.index[id];
var obj = objJsonResp.data[index];
This takes advantage of the fact you can index into objects using property names.
Of course, if you do that, you have to update the map when you modify the array, which could become a maintenance problem.
But if you’re not in control of the generation of the object, or updating the map of ids-to-indexes is too much code and/ora maintenance issue, then you’ll have to do a brute force search.
Brute Force Search (corrected)
Somewhat OT (although you did ask if there was a better way 🙂 ), but your code for looping through an array is incorrect. Details here, but you can’t use for..in to loop through array indexes (or rather, if you do, you have to take special pains to do so); for..in loops through the properties of an object, not the indexes of an array. Your best bet with a non-sparse array (and yours is non-sparse) is a standard old-fashioned loop:
var k;
for (k = someArray.length - 1; k >= 0; --k) < /* . */ >
Whichever you prefer (the latter is not always faster in all implementations, which is counter-intuitive to me, but there we are). (With a sparse array, you might use for..in but again taking special pains to avoid pitfalls; more in the article linked above.)
Using for..in on an array seems to work in simple cases because arrays have properties for each of their indexes, and their only other default properties ( length and their methods) are marked as non-enumerable. But it breaks as soon as you set (or a framework sets) any other properties on the array object (which is perfectly valid; arrays are just objects with a bit of special handling around the length property).
Javascript search inside a JSON object
You could just loop through the array and find the matches:
var results = [];
var searchField = "name";
var searchVal = "my Name";
for (var i=0 ; i < obj.list.length ; i++)
if (obj.list[i][searchField] == searchVal) results.push(obj.list[i]);
>
>
To find match element in array json.file and change it [node js]
You can use the Array#findIndex method to find the index of the first occurrence of 2 , then you can use the index to change the value to 3 .
const obj = "foods": 111,
"numbers": [1, 27, 5, 7, 0, 0, 2, 0, 0],
"surnames": [1, 1, 1, 1, 1, 1, 1, 1, 1],
"date": 0
>,
i = obj.numbers.findIndex(num => num === 2);
if (i > -1) obj.numbers[i] = 3;
>
console.log( obj );
Find object by property in JSON array
You can use array.find() method as,
var myArray = [ < "name": "Alice", "age": "20" >, < "name": "John", "age": "30" >, < "name": "David", "age": "25" >];
//Here you are passing the parameter name and getting the age //Find will get you the first matching objectvar result = myArray.find(t=>t.name ==='John').age;console.log(result);
How can I get the index from a JSON object with value?
You will have to use Array.find or Array.filter or Array.forEach .
Since your value is array and you need the position of the element, you will have to iterate over it.
Array.find
var data = [,,,,,,,,,];
var index = -1;
var val = "allInterests"
var filteredObj = data.find(function(item, i) if(item.name === val) index = i;
return i;
>
>);
console.log(index, filteredObj);
How to use array .filter() to search key value in JSON array of objects
You used filter fine, however, you have select the key from your json object.
Below is an example.
const jsonFile = "playlists" : [
"id" : "1",
"owner_id" : "2",
"song_ids" : [
"8",
"32"
]
>,
"id" : "2",
"owner_id" : "3",
"song_ids" : [
"6",
"8",
"11"
]
>,
"id" : "3",
"owner_id" : "7",
"song_ids" : [
"7",
"12",
"13",
"16",
"2"
]
>
]
>
const someId = 2
const result = jsonFile.playlists.filter(playlist => playlist.id !== someId)
console.log(result)
How to find value in json
Remove » as yours is not a valid string, remove » to make it a valid object literal, then you can iterate over the keys of the Object and check if it has the matching POSTCODE and if it has then return it’s corresponding state.
var data = < "1": < "state": "VIC", "postcode": "2600,2603,2605,2606" >, "2": < "state": "NSW", "postcode": "2259,2264" >>;
function getState(data, postcode) for(var x in data) < if(data[x].postcode && data[x].postcode.split(",").indexOf(postcode.toString())!=-1) return data[x].state; >return "Not Found"; >
alert(getState(data, "2600"));alert(getState(data, 2264));
Find the highest number in a json object with javascript and a corresponding index or another value
Once you have the highest amount, you can .findIndex to get the object with that amount.
const shots=[,,,,,];
const highest = Math.max(. shots.map(o => o.amount));
const index = shots.findIndex(o => o.amount === highest);
console.log(index, shots[index].id);
Search through a JSON object using JavaScript
As my opening contribution, i leave here a method i developed to search inside a JSON object for a specific value (could be or not the name of the object property). https://gist.github.com/killants/569c4af5f2983e340512916e15a48ac0 I’ll be happy if at least one person finds it usefull. Feel free to edit and improve it! Any feedback is welcome!
Top comments (13)
Without changing the structure, I would do the following:
const charSeparator = "/" /** * searches deep into an object recursively. * @param obj object to be searched * @param searchValue the value/key to search for * @param [valuesOnly=false] whether to skip comparing object keys * @param [maxDepth=20] maximum recursion depth (to avoid "Maximum call stack size exceeded") * @returns Paths on the object to the matching results */ function getValuePathInObject( obj, searchValue, valuesOnly = false, maxDepth = 20 ) if (!maxDepth) return [] const paths = [] for (const [curr, currElem] of Object.entries(obj)) if (!valuesOnly && curr === searchValue) // To search for property name too. paths.push(curr) > if (typeof currElem == "object") // object is "object" and "array" is also in the eyes of `typeof` // search again :D const deepPaths = getValuePathInObject( currElem, searchValue, valuesOnly, maxDepth - 1 ) const currDir = curr + charSeparator for (const path of deepPaths) paths.push(currDir + path) > continue > // it's something else. probably the value we are looking for // compares with `searchValue` if (currElem === searchValue) // return index AND/OR property name paths.push(curr) > > return paths >
- Use const and let , never var .
- Use for of loops instead of imperative key and numeric index iteration.
- Remove the debug logging
- Hoist the constant charSeparator out of the function (or you could inline the «/» literal)
- Only concatenate curr and charSeparator once, not in the loop.
- Remove unused variable i .
- Use early return (or rather, continue ).
- Use JSDoc, LMAO xD
- Use down-counting depth limit to pass only one number.
- Use defaults in the function parameters. These only check for undefined , not truthiness, so passing false and 0 won’t trigger them.