Set the JSON Key to increment inside a loop - javascript

I have an array within my json output from a php file which uses the key 0,1,2 etc
I am having trouble accessing the key through javascript. I'm not sure what the issue is with using numbers. All the other data has a text value key which I can access using data.arrayname.key. To get around the issue I would like to set the key to a string with a number at the end so I can reference it back in javascript easily.
The array is pushed to each time in a loop. Within the loop I have tried
$NoOfTips++;
$jsonKey = 'Tip' + $NoOfTips;
$TBarray[$jsonKey]=$line;
array_push($TBarray);
In theory each time the loop goes round NoOfTips should increase by 1 which would also change the key to Tip1,Tip2,etc but obviously something is amiss. Could somebody please explain how why the Key is not being set correctly.
Thanks

To answer the real issue - to access a numeric index in javascript, you can't use dot notation, you would instead use brackets:
var data = { tips: { 1: "one", 2: "two" }, other: [1, { test: "tested" }] }
console.log(data.tips[1], data.other[0], data.other[1].test)
// output: one 1 tested
For the php side, when you do array_push, you have to specify the array you are pushing to, as well as what you are pushing:
array_push($TBarray, $line)
for example. I'm not sure what you are going for there, though.

Related

I am getting one long string back from an API call that I need to turn into an array. The values are comma separated. What is the best way to do this?

I am working with data from an api that is returning values formatted like this for a few of the keys:
"key_one": [
"[\"Some Value One\",\"Some Value Two\",\"Some Value Three\"]"
],
"key_two": [
"[\"Some Value Four\",\"Some Value Five\"]"
],
The values of the keys come back as an array, but the array contains just one long string. I am looking for a way for taking THIS:
["[\"Some Value One\",\"Some Value Two\",\"Some Value Three\"]"]
and turning it into THIS:
["Some Value One","Some Value Two","Some Value Three"]
I have a feeling Regex would be best for this, but I am still a complete novice with Regex and my attempts so far havent gotten me anywhere.
I also attempted to do a basic for loop that looked for the presence of the " mark, and then checked to see if the character after wasnt a ',' and tried to push or += the letters into a string and then into an array at the end to return, but it was becoming a mess and wasn't working either.
I am hoping someone here can show me a more elegant solution.....
You ca try JSON.parse
const obj = {
"key_one": [
"[\"Some Value One\",\"Some Value Two\",\"Some Value Three\"]"
],
"key_two": [
"[\"Some Value Four\",\"Some Value Five\"]"
]
}
for (let keys in obj) {
obj[keys] = JSON.parse(obj[keys])
}
console.log(obj)

What is the best way to itterate over key value pairs nested in an index using javascript?

I am trying to sort sets of associated key value pairs. They look like this:
{"word":"a","votes":9326,"userMade":"FALSE","limiter":"FALSE"},
But organized into labeled subsets of preferably a string or perhaps an index if necessary.
The data-set is a vote-per-use table of most used english words being parsed into pages.
I will be appending them as text to other html elements due to the constraints my use case, makes it a bit tricky, however, for an example I could work with a simple console.log of the page value followed by the console.log of every word value stored within that page. I need the order preserved. so probably indexed. I will also need to be able to sort each page by the votes value, but I think I can figure the rest out for that.
I have found tutorials on how to search through key-value pairs, but I cannot find how to do all of the following with one solution:
A: access the value of word
B: maintain the order of the data-set, allowing me to append them to the matching html element
C: allows me the opportunity to change which set of elements I am appending to when i have finished looping through a single member of the parent index (the one recording the page)
I imagine it is some combination of for/of and for/in, but I'm getting a headache. Please help?
addl info:
function would run at app startup or when the dataset being examined is changed.
function would take a large dataset filled with around 200 page number values, each with 60+ sets of data like the one listed above, the contents of a single page index for example:
{"word":"a","votes":9326,"userMade":"FALSE","limiter":"FALSE"},
{"word":"aaron","votes":4129,"userMade":"FALSE","limiter":"FALSE"},
{"word":"abandoned","votes":1289,"userMade":"FALSE","limiter":"FALSE"},
{"word":"abc","votes":5449,"userMade":"FALSE","limiter":"FALSE"},
{"word":"aberdeen","votes":641,"userMade":"FALSE","limiter":"FALSE"},
{"word":"abilities","votes":2210,"userMade":"FALSE","limiter":"FALSE"},
{"word":"ability","votes":7838,"userMade":"FALSE","limiter":"FALSE"},
{"word":"able","votes":8649,"userMade":"FALSE","limiter":"FALSE"},
{"word":"aboriginal","votes":1837,"userMade":"FALSE","limiter":"FALSE"},
{"word":"abortion","votes":3232,"userMade":"FALSE","limiter":"FALSE"},
{"word":"about","votes":9295,"userMade":"FALSE","limiter":"FALSE"},
{"word":"above","votes":8818,"userMade":"FALSE","limiter":"FALSE"},
{"word":"abraham","votes":867,"userMade":"FALSE","limiter":"FALSE"},
{"word":"abroad","votes":4969,"userMade":"FALSE","limiter":"FALSE"},
{"word":"abs","votes":2415,"userMade":"FALSE","limiter":"FALSE"},
{"word":"absence","votes":4934,"userMade":"FALSE","limiter":"FALSE"},
{"word":"absent","votes":2937,"userMade":"FALSE","limiter":"FALSE"},
{"word":"absolute","votes":5251,"userMade":"FALSE","limiter":"FALSE"},
{"word":"absolutely","votes":5936,"userMade":"FALSE","limiter":"FALSE"},
{"word":"absorption","votes":285,"userMade":"FALSE","limiter":"FALSE"},
{"word":"abstract","votes":7946,"userMade":"FALSE","limiter":"FALSE"},
{"word":"abstracts","votes":1907,"userMade":"FALSE","limiter":"FALSE"},
{"word":"abuse","votes":7238,"userMade":"FALSE","limiter":"FALSE"},
{"word":"academic","votes":7917,"userMade":"FALSE","limiter":"FALSE"},
{"word":"academics","votes":1706,"userMade":"FALSE","limiter":"FALSE"},
{"word":"academy","votes":6755,"userMade":"FALSE","limiter":"FALSE"},
{"word":"acc","votes":6469,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accent","votes":1020,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accept","votes":7547,"userMade":"FALSE","limiter":"FALSE"},
{"word":"acceptable","votes":4907,"userMade":"FALSE","limiter":"FALSE"},
{"word":"acceptance","votes":7273,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accepted","votes":7684,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accepting","votes":1789,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accepts","votes":1535,"userMade":"FALSE","limiter":"FALSE"},
{"word":"access","votes":9031,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accessed","votes":2932,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accessibility","votes":5702,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accessible","votes":5662,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accessing","votes":2096,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accessories","votes":8875,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accessory","votes":5661,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accident","votes":5664,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accidents","votes":2991,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accommodate","votes":1807,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accommodation","votes":8059,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accommodations","votes":3885,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accompanied","votes":2532,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accompanying","votes":664,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accomplish","votes":1070,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accomplished","votes":2419,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accordance","votes":6434,"userMade":"FALSE","limiter":"FALSE"},
{"word":"according","votes":8282,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accordingly","votes":3003,"userMade":"FALSE","limiter":"FALSE"},
{"word":"account","votes":8996,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accountability","votes":3029,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accounting","votes":7459,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accounts","votes":7507,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accreditation","votes":1605,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accredited","votes":3027,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accuracy","votes":6779,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accurate","votes":6427,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accurately","votes":1493,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accused","votes":2853,"userMade":"FALSE","limiter":"FALSE"},
{"word":"acdbentity","votes":1389,"userMade":"FALSE","limiter":"FALSE"},
and the output would ultimately append the value paired with each word to a specific button through iteration, but also sorted by the page value.
each page is a set of buttons in a 3d object that looks like this:
the text is appended to each button which in turn is a 3d object embeded in an html object using aframe. I can make the appending code.
You can use Object.entries() to get the key value pairs of an object.
var words = [
{"word":"a","votes":9326,"userMade":"FALSE","limiter":"FALSE"},
{"word":"aaron","votes":4129,"userMade":"FALSE","limiter":"FALSE"}
];
words.forEach((wordEntry) => {
var keyValuePairs = Object.entries(wordEntry);
keyValuePairs.forEach((kv) => {
console.log(`key: ${kv[0]} value: ${kv[1]}`);
});
});
my latest attempt looks like this:
for (let p=1; p<129; p++){
for (let b=1; b<68; b++){
let pTpl = (p).toLocaleString(undefined, {minimumIntegerDigits: 3});
let bDbl = (b).toLocaleString(undefined, {minimumIntegerDigits: 2});
var `#fCont${pTpl}${bDbl}` = document.createElement('a-text');
`fCont${pTpl}${bDbl}`.setAttribute('value', 'engWordLib[p,b,0]');
`fCont${pTpl}${bDbl}`.setAttribute('votes', 'engWordLib[p,b,1]');
`fCont${pTpl}${bDbl}`.setAttribute('userMade', 'engWordLib[p,b,2]');
`fCont${pTpl}${bDbl}`.setAttribute('limiter', 'engWordLib[p,b,3]');
`fCont${pTpl}${bDbl}`.setAttribute('visible', 'false');
`fBtn${bDbl}`.appendChild(`#fCont${pTpl}${bDbl}`)
}
}
please note that I havent checked this for errors. I still think this code is to WET and I would prefer the key names for the properties be preserved in the datastructure rather than tacked on when it's appended to the page. I guess I could add a dimension to the array.... seems kind of messy when an object property value has the key value pairs right in it. cant get the iteration of objects in an array down though.... Will continue to persue a cleaner method.

Node.JS behaves strange

I have a variable called uids
var uids = [];
Then I write some value to it property
uids[16778923] = "3fd6335d-b0e4-4d77-b304-d30c651ed509"
But before it
if (!uids[user.id]) {
uids[user.id] = generateKey(user);
}
This thing behaves ok. If I try to get the value of it property
uids[currentUser.id]
It will give me a value of this property. If I try to call some methods like
Object.keys(uids);
It will give me, what I expected. And here the mystery comes...
uids;
RAM rest in piece. See the node eating ram
I am very confused now. What's wrong?
This is because you are creating a huge array and node will reserve memory for it - who knows what comes. I'd say that's a scenario where you would use a Map (or a plain object, but Map feels better here.
var uids = new Map();
var key = 456464564564654;
if (! uids.has(key)) {
uids.set(key, generateKey(user))
}
You are creating an empty array (length is zero), then you assign some value to an arbitrary index. This will make the array grow as big as the index and assign the value to that index. Look at this example using node.js REPL:
> var a = []
undefined
> a[5] = "something"
'something'
> a
[ , , , , , 'something' ]
> a.length
6
Instead of creating an array, you could create a Map() or an common javascript object (singleton). Javascript objects behave like Maps but only Strings can be used as keys. If you assign a Number to be key, javascript will convert it to String automatically.
Personally, I would go with objects because they perform better. Instantiating an object takes longer than instantiating a Map (and it doesn't seem like you need to create several groups of "uids"), but once done, adding new keys and retrieving values from any key in faster when using common objects. At least that's how things go in my node.js v6.7.0 on ubuntu 14.04 but you could try for yourself. And it would also make the least alteration to your code.
var uids = {} // common/ordinary empty javascript object instead of array.
if (!uids[user.id]) { // getting value from one key works the same.
uids[user.id] = generateKey(user) // assignment works the same.
}
////
uids[16778923] = "3fd6335d-b0e4-4d77-b304-d30c651ed509" // key will be "16778923".
uids[16778923] // getting value for key "16778923" can be done using 16778923 instead of "16778923".
////
uids[currentUser.id] // still returning values like this.
Object.keys(uids) // still returning an array of keys like this. but they are all Strings.

An explanation for this context of the.reduce() method and Object.assign()

Based on referencing the method/object definitions on MDN I am trying to construct a layman's step by step explanation of how the following script (from the previous post) is working to help my understand of it (and hopefully so I can adapt it further)
There's a few things I don't get so my attempt will probably seem a bit muddled but hoping someone can put me right where I'm off track/confused ...
(n.b. the encode function is just to encode html and required from node.js package)
var arr = {
"a": "Some strings of text",
"b": "to be encoded",
"c": "& converted back to a json file",
"d": "once they're encoded"
}
var encodedValues = Object.keys(arr).reduce(function(out,key) {
return Object.assign(out, {[key]: endcode(arr[key])})
}, {});
console.log(encodedValues);
Explanation
Create a variable “encodedValues” which will:
1 Object.keys(arr)
loop over and return the object arr’s properties in the order they are provided
2 .reduce(function(out,key)
First applying the following function to execute on each value in the array ("and reduce it to a single value" *):
3 return Object.assign(out, {[key]: endcode(arr[key])})
The function copies the values of all properties from the source object to a target object we will call “out”.
4 The source object has an encoding function {[key]: encode(arr[key])} applied to it so that where key is an object encode is applied to its property
5 }, {});
I assume this part , {} is the initialValue for .reduce i.e. the value used as the first argument to the first call of the callback, which starts as an empty object?
6
Object.keys returns an array (of the given object arr's encoded properties in the order they were provided)
7 which is then logged to the console
*I don't understand how or why we "reduce it to a single value" in this case??
Doesn't that suggest a concatination of the values is part of the process:
"Some strings of text" + "to be encoded" + "& converted back to a json file" + "once they're encoded". I don't really get how or why this is part of the working solution
Thanks!
What reduce() does is loop over the array, call your function for each item, and each time, it passes your function the return value of the previous iteration so that you can "build upon" it.
For example, you could use reduce() to total up an array of numbers. The iterator function would take in the running total, add to it, and then return the new total. Or, you could use it to concatenate a bunch of strings, where the iterator takes in the existing string, concatenates something onto it, and then returns the new string.
In this case, you're simply taking in an object (the parameter named out), doing stuff to it, then returning it so that the next iteration can keep working on it. When reduce() gets through all the keys, it will return the object you've been building upon. That goes into your encodedValues variable.

Searching a key in javascript object

I have a building a chrome extension, I have following data as
var data = {}
data["Five, ok"] = "another one"
chrome.storage.sync.set(data)
chrome.storage.sync.get(function(content){console.log(content)})
>> {'Five, ok': "Another one ", 'ok, done': "New one"}
This can grow bigger with many values. (Key is a comma separated value).
I want to get all keys which include (2 different cases, this are user give values)
1. ok
2. done
this values are dynamic, what is the best way to achieve this in JavaScript/ jquery
chrome.storage.sync.get(function(content) {
var keys = Object.keys(content);
var keysOK = keys.filter(function(key){ return key.search(/\b(ok|done)\b/i) });
console.log(keysOK);
});
/\b(ok|done)\b/i finds the keys containing either ok or done
/\bok\b/i finds the keys containing ok
/\bdone\b/i finds the keys containing done
The i at the end makes the search case-insensitive.
As #charlietfl commented it's not efficient. However chrome.sync doesn't allow more than 100kB of data anyway so it's probably not an issue.

Categories

Resources