Can we iterate through json in javascript without using for..in - javascript

I have a requirement to throw a 400 Bad request error if the json payload contains duplicate keys. I am using below code to fetch all attributes in an array.
var arrayObj = [];
var attrArr = [];
var arr = {
"serviceNumer": "1612045709",
"customerRefNumber": "TCreateS9",
"customerRefNumber": "TCreateS9"
};
for (var key in arr) {
arrayObj.push(key, arr[key]);
}
console.log("arrayObj", arrayObj);
for (var i = 0; i < arrayObj.length; i = i + 2) {
attrArr.push(arrayObj[i]);
}
console.log(attrArr);
When I iterate using for..in, the duplicate keys get overridden. So please help me with any alternate approach.

JavaScript objects cannot have duplicate keys. All the keys must all be unique.
Go through the following links, this will clear your doubts StackOverflow JSObj and Finding and solving issues for duplicate keys

your JSON impementation can't handle duplicate keys,
if you take the object you've got from the JSON and convert it back to JSON, and then compare the number of colons in the string against the original. If there are duplicate keys in the original there will be fewer colons in the new JSON.
Such a check is suitable to give warning messages to noobs, but it's not bulletproof. An attacker could use escapes for colons in string values resulting in an increased count. if the requiremnt is critical you'll need to modify the JSON parser to do the check.

A JSON Object can't have duplicate Keys.
If you are getting your payload as string than you can do following:
var input = '{"serviceNumer":"1612045709","customerRefNumber":"TCreateS9","customerRefNumber":"TCreateS9"}';
if(input === JSON.stringify(JSON.parse(input)))
console.log("input has No Duplicate");
else
console.log("input has Duplicate");
here JSON.parse will convert input to JSON object and will remove duplicate keys
Hope this help you:)

you just dont know, keep do it
//you can hard code it or write it
var arr = {
"serviceNumer": "1612045709",
"customerRefNumber": "TCreateS9",
"customerRefNumber": "TCreateS93333"
};
//but when you call it it just will show the last element
console.log(arr.customerRefNumber)
/*
its like you say
var ac = 1
var ac = 3
console.log(ac)
it will show 3
*/
//make it different
var arr2 = {
"serviceNumer": "1612045709",
"customerRefNumber": "TCreateS9",
"customerRefNumber2": "TCreateS9"
};
var a = Object.getOwnPropertyNames(arr).sort()
var b = Object.getOwnPropertyNames(arr2).sort()
console.log(a)
console.log(b)

Related

convert json values in comma separated string using javascript

I am calling a third party web api, which returns data like this:
{"name":"Marine Lines","name":"jerry"}
I would like to convert this to a Json array, I could do a split by comma first and then by ":". but wondering if there are some better ways?
If the Web API return an object, then you can directly use dot-notation to access the value.
var x = {"name":"Marine Lines","name":"jerry"};
var name = x.name;
console.log(name);
Else if it is a string then you can parse it first using JSON.parse() and then do the same thing.
var x = '{"name":"Marine Lines","name":"jerry"}';
x = JSON.parse(x);
var name = x.name;
console.log(name);
First of all, your object has the name key twice, which means only the latter will be saved. As regards saving your object's values in an array, the following will do:
var
object = {"a": "Marine Lines", "b": "jerry"},
array = [];
/* Iterate over every enumerable property of the object. */
for (var key in object) {
/* Insert the value in the array. */
array[array.length] = object[key];
}
/* Log the created array. */
console.log(array);

Splitting an array of numbers and non-numbers into two separate arrays

I'm very new to javascript and I'm trying to create a function that takes a mixed input of numbers and then loops through the array in order to sort them into two newer arrays so I can manipulate them further.
So if I have an input of
1,a,2,b,3,c,4,d,
I want to make two new arrays of
1,2,3,4 and a,b,c,d
So far I've been able to split the input string at the comma, so that I now have
1a2b3c4d
all I need to be able to do now is just separate the numbers and non-numbers. I was thinking of using two loops: one that checks
if(isNan.array[n] == True )
and then trying to find a way to store the letters into a variable using the loop and then using another loop to do so for the numbers using another if function.
Is this how I should do it, and do you have any advice on how to go about it?
Edit:
I now have this code to check for letters:
if (isNaN(splitResult[L])) {
for (i = 0; i < splitResult; i++) {
letterArray.add(splitResult[L]);
L = L + 1
When I try to output the results to a box to count letters (using the variable L), nothing shows up. I doubt I've made a new array
just for completion, split the string into array first :)
let yourString = '1a2b3c4d';
let yourArray = yourString.split('');
let letterArray = [];
let numberArray = [];
yourArray.forEach(item => {
if(isNaN(item) && typeof item === 'string'){
letterArray.push(item);
}
else if(!isNaN(item) {
numberArray.push(item);
}
});
console.log(letterArray, numberArray);
All you need to do is loop through the array, you can use the Array prototypes forEach. Or you can use the normal for loop to check through each element of the array. You can now check if each element isNaN and then push into the right array appropriately. You can use the snippet below
const yourArray = ['1','a','2','b','3','c','4','d'];
const letterArray = [];
const numberArray = [];
yourArray.forEach((eachItem) => {
if(isNaN(eachItem)){
letterArray.push(eachItem);
} else {
numberArray.push(eachItem);
}
});
console.log(letterArray, numberArray);

Named objects and collection of them

not sure how to ask tbh :)
I'm used of PHP's associative arrays so much that I struggle to understand how to create an "named array" of objects.
Example:
I have two arrays, two ints and one boolean. This represents one of my entities. I have multiple entities on which I'm doing some work.
In PHP I would write:
$entitites[$entitity_id]['items'][] = $item;
$entitites[$entitity_id]['items_status'][] = $item_status;
$entitites[$entitity_id]['items_count']++;
and so on..
How do I do this with objects in JS?
var entities = {items:[], items_status: [], items_count: 0};
entities[entity_id].items.push(item)
How does one name his object for later access (via name or in my case, entity_id?)
This code doesnt work for me to this extend that my webpage goes blank without any errors produced :S
I also tried this:
var entities = {};
var entity = {items:[], items_status: [], items_count: 0};
but then I dont know how to always add values to already existing object in entities object and how to call that exact object via name eg. entity_id.
Halp :(
Keep entities as an object. Then you can just go ahead and add each entity_id as a key and an object which has all the details of that entity as the value.
var entities = {};
entities["1234"] = {
"items" : [],
"items_status" : [],
"items_count" : 0
};
There are 2 types involved here: Objects & Arrays.
Arrays are simple and you're probably familiar with them from any other language:
var myArray = []; // this is an empty array
myArray[0] = 1;
myArray[1] = 2;
myArray[2] = 3;
// you could also use "var myArray = [1, 2, 3];" instead
alert(myArray[1]); // alerts the value 2
Note: arrays are actually objects, and can have non-index properties as well
You can also use various array functions such as .push(), .pop(), .shift() and so on to mutate the array instead.
Objects share the square brackets notation, but the purpose is different:
var myObject = {}; // this is an empty object
myObject[0] = 1;
myObject[1] = 2;
myObject[2] = 3;
alert(myObject[1]); // alerts the value 2
// but also...
myObject['prop'] = 4;
alert(myObject['prop']); // alerts the value 4
// and
myObject.prop2 = 5;
alert(myObject.prop2); // alerts the value 5
// and lastly
alert(myObject.prop); // alerts the value 4
So while arrays are accessed by index, objects are accessed by property names.
As for your entities, it looks like an array of objects. Lets see how we can do that:
function Entity() {
this.items = [];
this.items_status = [];
this.items_count = 0;
}
var entitites = [];
entities.push(new Entity());
entities[0].items = [1, 2, 3];
entities[0].items_status = ['good', 'good', 'poor'];
entities[0].items_count = 3;
Or you can wrap insertion in a more elegant function:
Entity.prototype.insert(item, status) {
this.items.push(item);
this.items_status.push(status);
this.items_count++;
}
entities[0].insert(4, 'excellent!');
If you want to keep control of the indexes in your JS array you can do so by not using .push() :
var entities = [];
entities[5] = {items:[], items_status:[], items_count:0};
Just replace 5 by your integer entity_id variable, and there you go.
You can use a regular javascript object to create the associative array you're looking for.
Actually it's PHP's implementation that's abit off but all they do is call it different (associative array) to most other language that simply refer to it as an object or hash.
You can use numeric keys in JS and still access them with the [] square brackets.
It works like this:
var my_obj = {};
my_obj[5] = 'any value';
console.log(my_obj); // {5: 'any value'}
JS will not add any redundant undefined to missing indexes either so when looping over the collection you won't loop over undefined.
Also, I can access the object by using the key as a string or as number so you won't have to check if the key is the right type. Taken from the above example:
console.log(my_obj['5']); // 'any value'
console.log(my_obj[5]); // 'any value'
JS Objects are the equivelant of PHP assoc arrays except JS objects are much more flexible than PHP's associative arrays.
The only downside to this is that you can't have duplicate keys.
No two keys may exist that share the same name, in an array if you .push(an_item) it will create a new index making even a duplicate data entry unique but when overwriting a key with a new value only the last value will persist, mind that :)

How to convert a string to an array based on values of another array in JavaScript

I have some data that I'm trying to clean up. For the field in question, I know what the possible values are, but the value is stored in a concatenated string and I need them in an array. Here is what I would like to do:
var valid_values = ['Foo', 'Bar', 'Baz'];
var raw_data = ['BarFoo','BazBar','FooBaz'];
desired_result = [['Bar','Foo'],['Baz','Bar'],['Foo','Baz']];
I'm not sure what this is called, so I hope this isn't a duplicate.
You can iterate over each data value, searching for allowed string with indexOf or contains and returning successful matches as array.
Here's my version of code and working example at jsFiddle:
var out = raw_data.map(function (raw) {
return valid_values.filter(function (value) {
return raw.contains(value);
});
});
//out === [['Bar','Foo'],['Baz','Bar'],['Foo','Baz']];
I assumed that output match order isn't important.
This is assuming some things about your data:
you need to split strings into 2-item pairs
input & terms are case-sensitive
you won't be dealing with null/non-conforming inputs (requires more edge-cases)
In that case, you'd want to do something like this:
// for each item in the desired result, see if it's a match
// at the beginning of the string,
// then split on the string version of the valid value
function transform(input){
for(i = 0; i < len; i++) {
if (input.indexOf(valid_values[i]) === 0) {
return [ valid_values[i], input.split(valid_values[i])[1] ];
}
}
return [];
}
// to run on your input
var j = 0, raw_len = raw_data.length, desired_result = [];
for(; j < raw_len; j++) {
desired_result.push(transform(raw_data[j]));
}
This code is pretty specific to the answer you asked though; It doesn't cover many edge cases.

Get last element of a JSON object in JavaScript

I got a json object in JavaScript like:
var json = {"20121207":"13", "20121211":"9", "20121213":"7", "20121219":"4"};
without knowing the name of the last key. (The keys are in ascending order)
How can I read the value (and key) of the last element?
var highest = json[ Object.keys(json).sort().pop() ];
Object.keys (ES5, shimmable) returns an array of the object's keys. We then sort them and grab the last one.
You can't ensure order in a for..in loop, so we can't completely rely on that. But as you said the keys are in ascending order, we can simply sort them.
Try this:
var lastKey;
var json = {"20121207":"13", "20121211":"9", "20121213":"7", "20121219":"4"};
for(var key in json){
if(json.hasOwnProperty(key)){
lastKey = key;
}
}
alert(lastKey + ': ' + json[lastKey]);
If you don't need to support old JS engines:
var lastKey = Object.keys(json).sort().reverse()[0];
var lastValue = json[lastKey];
Don't assume the keys are in order. Get the keys, and then sort them, and then grab that largest value after the sort.
Object keys are typically unordered, but looking at the keyset you are using, I made the assumption that you are looking for the highest date in the json keys:
var json = {"20121207":"13", "20121211":"9", "20121213":"7", "20121219":"4"};
function getMaxFromKeys(json) {
var m;
for (var i in json) {
if (json.hasOwnProperty(i)) {
m = (typeof m == 'undefined' || i > m) ? i : m;
}
}
return m;
}
var latestDate = getMaxFromKeys(json);
ECMCA script specifications (javascript specifications) do not require browsers to maintain order of the properties of an object.
Related to for-in this is what ECMCA 5 specs say:
"The mechanics and order of enumerating the properties (step 6.a in
the first algorithm, step 7.a in the second) is not specified."
Related to the Object.keys method:
"If an implementation defines a specific order of enumeration for the
for-in statement, that same enumeration order must be used in step 5
of this algorithm."
It does not make sense to say get the last defined property. You can sort the properties based on the name and get the last one, but if what you want is order then keep an array.
let obj = <your_object>
let last_key = Object.keys(obj)[Object.keys(obj).length - 1]
let last_value = <your_object>.last_key
OR
let last_value = Object.values(obj)[Object.values(obj).length - 1]
getJsonLastElement(json)
{
let len = json.length
return json[len - 1]
}

Categories

Resources