How to push a consecutive number as string into an json object? - javascript

I want to push some data into a JSON file, which has just only consecutive numbers as keys and hash string as a value.
var readyFiles = JSON.parse(fs.readFileSync('requests.json', 'utf8'));
console.log(readyFiles)
const num = readyFiles.length
readyFiles.fileHashList.push({ num : _fileHash })
console.log(readyFiles)
var json = JSON.stringify(readyFiles)
fs.writeFileSync('requests.json', json, 'utf8');
the expected output should be like that:
{
"fileHashList": [
{
"1": "QmWpVdqGqPGo9ApLErzxBYfxD2eABKtYCQYCXQpnbYWjro"
},
{
"2": "QmTYsKnWBsVQTC1ioBHX7VWeY9tZLJXXzxuVkGiBSdBDea"
},
{
"3": "QmPiszxoFdCfwtLvWihaqFuBVpbU168WNVDbHUqtmuCDj3"
},
{
"4": "QmdLQ8TTg7EvJ4jvvbQiNWQUniKz6yKQugsvzVTMwNLJu1"
},
{
"5": "QmcziropQqSUDbNfAkYBwsLQXdEVf9N88Nqz4K1dfKeQGL"
},
{
"6": "QmSiEYVCY8G7zrc5X8UamkA6TymDyAg8dM39L7qnNFt7tY"
}
]
}
but instead, the actual behaviour is that:
{
"fileHashList": [
{
"1": "QmWpVdqGqPGo9ApLErzxBYfxD2eABKtYCQYCXQpnbYWjro"
},
{
"2": "QmTYsKnWBsVQTC1ioBHX7VWeY9tZLJXXzxuVkGiBSdBDea"
},
{
"3": "QmPiszxoFdCfwtLvWihaqFuBVpbU168WNVDbHUqtmuCDj3"
},
{
"4": "QmdLQ8TTg7EvJ4jvvbQiNWQUniKz6yKQugsvzVTMwNLJu1"
},
{
"5": "QmcziropQqSUDbNfAkYBwsLQXdEVf9N88Nqz4K1dfKeQGL"
},
{
"num": "QmSiEYVCY8G7zrc5X8UamkA6TymDyAg8dM39L7qnNFt7tY"
}
]
}
as you can see, there is 'num' as key in the last entry.
How can I have the next number of the keys there, espacially "6" in the above case?

const readyFiles = JSON.parse(fs.readFileSync('requests.json', 'utf8'));
const readyFilesKeys = Object.keys(readyFiles.fileHashList);
const countKey = readyFilesKeys.length + 1;
readyFiles.fileHashList.push({ [countKey]: _fileHash })
var json = JSON.stringify(readyFiles)
fs.writeFileSync('requests.json', json, 'utf8');
count the keys and + 1
use brackets [] outside the keys makes it possible, as #Taplar commented (THANKS :) )

Related

How can I get all possible paths to traverse the tree?

The question is: How can I get an array of all tree paths?
In this example there are 5 ways:
[
[{ 1: "2" }, { 3: "4" }],
[{ 1: "2" }, { 3: "5" }],
[{ 1: "6" }, { 7: "8" }],
[{ 1: "6" }, { 7: "9" }, { 10: "11" }],
[{ 1: "6" }, { 7: "9" }, { 10: "12" }],
]
I can loop through all nested objects with recursion, but I don't know how to get that array...
Here is my code:
const data = {
"1": {
"2": {
"3": {
"4": {},
"5": {}
}
},
"6": {
"7": {
"8": {},
"9": {
"10": {
"11": {},
"12": {}
}
}
}
}
}
}
let list = [];
function iterate(object) {
if( object !== null && typeof object == "object" ) {
Object.entries(object).forEach(([key, value]) => {
if( JSON.stringify(value) != JSON.stringify({})) {
let obj = {};
obj[key] = Object.keys(value)
list.push(obj);
iterate(value);
}
});
}
}
iterate(data);
I would first create a recursive function that will iterate the paths in a more intuitive format: each path will be represented as an array of nodes. This function could be a generator function.
Then create a mapping function that converts such path to a list of objects with single key/value pairs, assuming the given path has an even number of nodes.
Finally, use Array.from to consume the iterator returned by the generator function, and use the mapping argument to perform the mapping defined by the second function:
function* iteratePaths(object) {
const entries = Object.entries(Object(object));
if (entries.length == 0) return yield [];
for (const [key, value] of entries) {
for (const path of iteratePaths(value)) {
yield [key, ...path];
}
}
}
const toPairs = path =>
path.reduce((acc, val, i) => i % 2 ? [...acc, { [path[i-1]]: val }] : acc, []);
// Example input:
const data = {"1": {"2": {"3": {"4": {},"5": {}}},"6": {"7": {"8": {},"9": {"10": {"11": {},"12": {}}}}}}}
const result = Array.from(iteratePaths(data), toPairs);
console.log(result);

How To Get An Object Value

Consider this data:
{
"id": 1,
"title": "Title one",
"category_data": {
"2": "Team",
"7": "Queries"
}
},
I loop through my data to all the categories using this function:
remove_category_duplicates: function () {
// Get all categories and remove duplicates
let data = {}
this.info.forEach(i=>{
Object.assign(data,i.category_data);
})
return data;
},
This returns an object, like so:
Object {
12: "Fax",
2: "Team",
6: "Questions",
7: "Queries"
}
How can I also return just the value (Ex, Fax)? I want to then push those name values into an array.
Thanks
To return only values you can use the Array.map function like this:
let arr = this.info.map(val => val.category_data);
...or use the newer Object.values() as mentioned in the comments ;)
You can push values by this way
var info = [{
"id": 1,
"title": "Title one",
"category_data": {
"2": "Team",
"7": "Queries"
}
}];
var remove_category_duplicates = function () {
// Get all categories and remove duplicates
let data = [];
for (var i in info) {
if (info[i] && info[i].category_data) {
var category_data=info[i].category_data;
for (var j in category_data) {
data.push(category_data[j]);
}
}
}
console.log(data)
return data;
};
remove_category_duplicates();

Map object values to keys - Javascript

I have an array from an API call.
var response = {
"data": {
"data": [{
"1": "Arun",
"index": "name"
}, {
"1": 70.78,
"index": "score"
}]
}
}
I connect to a lot of other API's and they return me a similar response but the keys change. Sometimes it might be
var response = {
"data": {
"data": [{
"values": "Harry",
"index": "name"
}, {
"values": 45,
"index": "score"
}]
}
}
var response = {
"data": {
"data": [{
"4": "Richard",
"index": "name"
}, {
"4": 98,
"index": "score"
}]
}
}
I would like to get an array like this.
[
{
name: 'Arun',
score: 70.78
}
]
This is what I did.
var response = {
"data": {
"data": [{
"1": "Arun",
"index": "name"
}, {
"1": 70.78,
"index": "score"
}]
}
}
const result = [];
const mappedData = _.map(response.data.data, (item) => {
return {
[item.index]: item[1]
};
});
const resultObject = _.reduce(mappedData, (result, currentObject) => {
for (const key in currentObject) {
if (currentObject.hasOwnProperty(key)) {
result[key] = currentObject[key];
}
}
return result;
}, {});
result.push(resultObject)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
So instead of hardcoding "1" or "values" in the map function, is there a more universal way to get the key and achieve the same result?
Thanks.
Use reduce rather than map, so you're updating the same object, not creating an array.
And since the property containing the value can vary, I use a loop to look for the first property that isn't named index, and use its value.
var response = {
"data": {
"data": [{
"1": "Arun",
"index": "name"
}, {
"1": 70.78,
"index": "score"
}]
}
}
const mappedData = response.data.data.reduce((acc, item) => {
var value;
// find the property that isn't named "item"
for (var i in item) {
if (i != "index") {
value = item[i];
break;
}
}
acc[item.index] = value;
return acc;
}, {});
console.log(mappedData)
There's no need for lodash for this, the built-in reduce function is fine (but _.reduce will work similarly).
Since you only care about the values of that object and it only has two keys you can do this quite easily in lodash with reduce & fromPairs:
var response = { "data": { "data": [{ "1": "Arun", "index": "name" }, { "1": 70.78, "index": "score" }] } }
const rv = (o) => _.reverse(_.values(o))
const r = _.reduce(response.data.data, (a,c) => _.fromPairs([rv(a), rv(c)]))
console.log(r)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>
The same thing converted to ES6 would be:
var response = { "data": { "data": [{ "1": "Arun", "index": "name" }, { "1": 70.78, "index": "score" }] } }
const rv = (o) => Object.values(o).reverse() // reverse values
const fp = (arr) => arr.reduce((r, [k,v]) => (r[k] = v, r), {}) // from pairs
const result = response.data.data.reduce((a,c) => fp([rv(a), rv(c)]))
console.log(result)
The main idea here is to first get the object values in an array form, reverse them so the key & value are in the correct order and then reduce that array via from pairs to create the final object.
The main advantage of this approach is that we never deal with the object keys and only focus on the values which is what you really care about. This way the keys can be any value and it would still not matter.
You could try deleting the key-pair index and using the first value of the resulting object:
const mappedData = _.map(response.data.data, (item) => {
var tempObj = Object.assign({}, item)
var index = tempObj.index;
delete tempObj.index;
var otherData = Object.values(tempObj)[0];
return {
[index]: otherData
};
});
Just modified the #barmar approach. I have used Object.keys to get keys from object. This will remove the any hard-coded dependency.
var response = {
"data": {
"data": [{
"1": "Arun",
"index": "name"
}, {
"1": 70.78,
"index": "score"
}]
}
}
const mappedData = response.data.data.reduce((acc, item,i) => {
var key = Object.keys(item);
acc[item[key[1]]] = item[key[0]]
return acc ;
}, {});
console.log(mappedData)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

How do I search a JSON object for a specific string value?

I want to search a JSON object to check if it contains string values stored in an array. and figure out the parent elements.
var searchVal = ['name_1a','name_2y','name_3x'];
var json = {
"location": {
"title1x": {
"1": "name_1x",
"2": "name_2x",
"3": "name_3x",
},
"title2y": {
"1": "name_1y",
"2": "name_2y",
"3": "name_3y",
},
}
"object": {
"title1a": {
"1": "name_1z",
"2": "name_2z",
"3": "name_3z",
},
"title2b": {
"1": "name_1a",
"2": "name_2a",
"3": "name_3a",
},
}
};
I want to pass the results into a function. And deal with them separate.
name_1a -> function(title2b, object)
name_2y -> function(title2y, object)
name_3x -> function(title1x, location) etc.
.
This is what I have tried so far. I can't seem to figure out how to gothrough the entire JSON object
var searchVal = ['name_1a','name_2y','name_3x'];
for (var i=0 ; i < searchVal.length ; i++){
for (var k=0 ; k < ????.length ; k++)
{
if (json.???????? == searchVal[i]) {
results.push(???????);
console.log(results);
}
}
}
with the code below you can find what you are looking for recursively:
var json = {
"location": {
"title1x": {
"1": "name_1x",
"2": "name_2x",
"3": "name_3x",
},
"title2y": {
"1": "name_1y",
"2": "name_2y",
"3": "name_3y",
},
},
"object": {
"title1a": {
"1": "name_1z",
"2": "name_2z",
"3": "name_3z",
},
"title2b": {
"1": "name_1a",
"2": "name_2a",
"3": "name_3a",
},
}
};
var searchTest = function(varToSearch, jsonData) {
for (var key in jsonData) {
if(typeof(jsonData[key]) === 'object') {
searchTest(varToSearch, jsonData[key]);
} else {
if(jsonData[key] == varToSearch) {
console.log(jsonData[key]);
}
}
}
}
searchTest('name_1a', json);
Reference:
get data from dynamic key value in json
get value from json with dynamic key
https://trinitytuts.com/tips/get-dynamic-keys-from-json-data/
How do I enumerate the properties of a JavaScript object?
Check if a value is an object in JavaScript
What about something like this:
var json = {
"location": {
"title1x": {
"1": "name_1x",
"2": "name_2x",
"3": "name_3x",
},
"title2y": {
"1": "name_1y",
"2": "name_2y",
"3": "name_3y",
},
},
"object": {
"title1a": {
"1": "name_1z",
"2": "name_2z",
"3": "name_3z",
},
"title2b": {
"1": "name_1a",
"2": "name_2a",
"3": "name_3a",
"foo": [{
"x": "aaa",
"y": "bbb",
"z": {
"k": "name_3y"
}
}, {
"x": "aaa",
"y": "bbb",
"z": {
"k": "name_3y",
"bar": [{
"op": "test",
"fooAgain": {
"x": "name_3y"
}
}]
}
}]
},
}
};
function search(what, where) {
var results = [];
var parentStack = [];
var searchR = function(what, where) {
if (typeof where == "object") {
parentStack.push(where);
for (key in where) {
searchR(what, where[key]);
};
parentStack.pop();
} else {
// here comes your search
if (what === where) {
results.push({
parent: parentStack[parentStack.length - 1],
value: where
});
}
}
}
searchR(what, where);
return results;
}
search("name_3y", json).forEach(function(value, key) {
var out = "parent: \n";
for (key in value.parent) {
out += " key: " + key + " - value: " + value.parent[key] + "\n";
}
out += "\nvalue: " + value.value;
alert(out);
});
The search function will search for a value that is exactly equal inside a json object. You can use it to search for each element of an array for example, just adjust the code. A stack was necessary, since we need to keep track of the parents. I modified your json to insert more levels. The values of the results are objects with two attributes. I think that with this you can do what you need. You can, of course, modify my code to use regular expressions intead of strings in your search. It would be more powerfull.
var searchVal = ['name_1a','name_2y','name_3x'];
var json = {
"location": {
"title1x": {
"1": "name_1x",
"2": "name_2x",
"3": "name_3x",
},
"title2y": {
"1": "name_1y",
"2": "name_2y",
"3": "name_3y",
}
},
"object": {
"title1a": {
"1": "name_1z",
"2": "name_2z",
"3": "name_3z",
},
"title2b": {
"1": "name_1a",
"2": "name_2a",
"3": "name_3a",
}
}
};
var getTitle=function(json,val){
for (var key in json) {
var titles= json[key];
for (var tit in titles) {
var names=titles[tit];
for (var name in names) {
var string=names[name];
if(string===val)
return tit;
}
}
}
}
searchVal.forEach(function(valToSearch){
console.log(getTitle(json,valToSearch));
});

Pull out certain nested objects

I have a series of nested objects like this:
data = {"12345":{"value":{"1":"2","3":"4"}},
{"12346":{"value":{"5":"6","7":"8"}},
{"12347":{"value":{"9":"0","11":"22"}}
I would like to create a function to grab certain objects within this grouping. For example...
grabObject(12345);
would return:
{"value":{"1":"2","3":"4"}}
Any help you could provide would be great.
You don't need anything more than this:
function grabObject(id) {
return data[id];
}
After making some fixes to your syntax, here's a working jsFiddle: http://jsfiddle.net/jfriend00/04no0bvm/
var data = [
{
"12345": {
"value": {
"1": "2",
"3": "4"
}
}
},
{
"12346": {
"value": {
"5": "6",
"7": "8"
}
}
},
{
"12347": {
"value": {
"9": "0",
"11": "22"
}
}
}
];
function grabObject(id) {
var result;
for (i = 0; i < data.length; i++) {
for (var k in data[i]){
if(k == id) {
result = data[i][k];
}
}
}
return result;
}
console.log(grabObject('12345'));
This is the code I tested check and let me know

Categories