Summation of JSON values in an Array - javascript

I have a set of JSON data stored in an array. The JSON looks like this:
{
"id": "1",
"key": "2"
}
and I'm trying to sum all of the "key" values inside the array of JSON strings with a for/in loop.
var total = 0;
for (var object in array) {
total += object.value;
}
The expected output is 3. However, this arrangement seems incorrect. I'm working in Node.js. Can anyone point me in the right direction?

If we have an array looking like this:
var array = [{id: "one", key: 2}, {id: "two", key: 8}]
You can simply get the total like that:
var total = array.reduce((x,y) => x + y.key, 0)
However, if you have a JSON string, where the values are also strings (like [{"id":"one","key":"2"},{"id":"two","key":"8"}]'), then you need to parse the JSON first and parse the values as numbers:
JSON.parse(array).reduce((x,y) => x + Number.parseFloat(y.key), 0)

What you have is not an array of objects, but one object with several properties.
You can use Object.keys() to get the properties as an array, then map to retrieve the values for each of those properties, and finally reduce on that array to calculate the sum:
const obj = {
"id": "1",
"key": "2"
}
const total = Object.keys(obj) // Get keys
.map( key => +obj[key] ) // Get values as numbers
.reduce ( (a,b) => a+b ); // sum up
console.log(total);

Related

Javascript associate array gives many undefined fields

I have an associate array with the key is the Id of the item. For example, the item id is 104, therefore the id of the object will be array[104] = {item.info};
So I have this in my component, but every time I am outputting my array it shows 1-103 values and all of them are null. How would I get rid of it and make the array output only what is stored.
JavaScript does not have associative array like in PHP.
What JavaScript has that is most similar to associative array is an object. The difference is that an object is not iterable, while an associative array is iterable.
What you currently do is basically:
const data = []; // [] is an array
data[10] = {
item: 1
};
console.log(data);
What you need to do should be something like this:
const data = {}; // {} is an object
data[10] = {
item: 1
};
console.log(data);
When you do json_encode() in PHP, it is actually converting associative array into a JSON, which is a valid JavaScript object, which do not support associative array as well.
So what it does would be something like this:
$data = [
'10' => [
'item' => 1
]
];
echo json_encode($data);
// output => { "10": { "item": 1 } }
Notice the {} syntax instead of [] syntax.
array doesn't have key, value. it just have value
if you use key, value data form, you should use object
let item = {104: item.info}
how to use object :
item[104]

How do I join two array and create json array of objects

SO I have array1 with values ["folderid":"DTSZ", "folderid":"IEACF6FVGG", "folderid":"IEACKQC6A"] and another array 2 with values ["title":"firsttitle", "title":"second","title":"thirdtitle"]
Now lets say using javascript i want to save it as json object.
[
{"folderid":"DTSZ","title":"firsttitle"},
{"folderid":"IEACF6FVGG", "title":"second"},
{"folderid":"IEACKQC6A", "title":"thirdtitle"}
]
I trying looping and concat but didn't work properly.
array1= ["folderid":"DTSZ", "folderid":"IEACF6FVGG", "folderid":"IEACKQC6A"] ;
array2 = ["title":"firsttitle", "title":"second","title":"thirdtitle"];
Get array with json objects
[
{"folderid":"DTSZ","title":"firsttitle"},
{"folderid":"IEACF6FVGG", "title":"second"},
{"folderid":"IEACKQC6A", "title":"thirdtitle"}
]
In JavaScript an array has just values, in you examples the array is invalid since you try to add direct key: values elements . i.e.
["folderid":"DTSZ"] // invalid !! (notice semicolon)
["folderid", "DTSZ"] // VALID (notice comma)
If you want to translate to a valid array and then to an object, you could use something like entries, which are array of arrays.
Let's take your first example and convert it to entries:
const arr1 = [["folderid", "DTSZ"], ["folderid", "IEACF6FVGG"], ["folderid","IEACKQC6A"]]
Then to convert this to object you can use Object.fromEntries just like this:
const obj1 = Object.fromEntries(entries);
So, focus first to convert your initial invalid arrays to entries, and then the job is done!
use the following code.
var a = [{ "folderid": "DTSZ" }, { "folderid": "IEACF6FVGG" }, { "folderid": "IEACKQC6A" }]
var b = [{ "title": "firsttitle" }, { "title": "second" }, { "title": "thirdtitle" }]
var newObject = a.map((o, index) => {
const temp = Object.assign(o, b[index]);
return temp;
});
console.log('output ---- ', newObject)

How to do mapping for two objects and array in javascript

I have such a object and array which I received response from my server. I need to convert that to second format at below in order to print the value in the website. Is this something need to do object mapping? or parse JSON or please kindly help.
{"header":["SEOUL","BUSAN","NAMPODONG"],"data":[[38,"CAPITAL","M31"]]},
Convert from Above to below
'{"SEOUL" : "38", "BUSAN" : "CAPITAL", "NAMPODONG" : "M31"}'
var finalObj = {};
response.header.forEach(function(item, index) {
finalObj[item] = response.data[0][index];
});
Above code is working fine as it create variable and loop for header and get its value and printed in html. the header and data are from the server so when I enter something let say "A" then it will look for SEOUL header then print 38 in html as tables are looks below.
key value : A
header : SEOUL BUSAN NAMPODONG
data : 38 CAPITAL M31
I do have a lot of data in the database, above is just an example. So let say I enter B then the B is not in database so I want to see the value "No found" in html but this code printing nothing so not sure whether it was proceed or not.
Create a variable & loop over the object.header to get each key and object.data[0] to get its value
var myObj = {
"header": ["SEOUL", "BUSAN", "NAMPODONG"],
"data": [
[38, "CAPITAL", "M31"]
]
}
var tempObj = {};
myObj.header.forEach(function(item, index) {
tempObj[item] = myObj.data[0][index]
})
console.log(tempObj)
As you received it from server – I assume that it is JSON string.
Basically you have two arrays here that you want to reduce to an object.
So I would do it like this:
const object = JSON.parse('{"header":["SEOUL","BUSAN","NAMPODONG"],"data":[[38,"CAPITAL","M31"]]}');
const result = object.header.reduce(function(accumulator, element, i){
accumulator[element] = object.data[0][i] // You had nested array here so I have to get first element.
return accumulator;
}, {});
console.log(result);
I assumed that nested array for data attribute is some kind of formatting mistake. If it's not – you have to map though it's elements first and only then reduce.
You can use zipObj from Ramda library.
The code would look like this:
const res = {"header":["SEOUL","BUSAN","NAMPODONG"],"data":[[38,"CAPITAL","M31"]]}
const obj = R.zipObj(res.header, res.data[0])
console.log(obj)
<script src="//cdn.jsdelivr.net/npm/ramda#latest/dist/ramda.min.js"></script>
You could map the new objects with the wanted keys.
The result is an array with objects, because your data is a nested array with actually only one array. But it looks like taht data could contain more than one row.
var data = { header: ["SEOUL", "BUSAN", "NAMPODONG"], data: [[38, "CAPITAL", "M31"]] },
result = data.data.map(a => Object.assign(...data.header.map((k, i) => ({ [k]: a[i] }))));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You can map the data array of arrays into another array of object using as keys the strings in header array:
function transform(obj) {
return obj.data.map(function(subArray) { // for each subArray in the data array
return subArray.reduce(function(o, val, i) { // create a new object o which...
o[ obj.header[i] ] = val; // has key-value pairs where value is the current element of subArray and key is its equivalent (item at the same index) from header array
return o;
}, {});
});
}
var obj = {"header":["SEOUL","BUSAN","NAMPODONG"],"data":[[38,"CAPITAL","M31"], [10,"OTHER","M01"]]};
var result = transform(obj);
console.log(result);
I think the responses above are good as they are, but here is an alternative using reduce in case you didn't know about it
var response = {
"header": ["SEOUL", "BUSAN", "NAMPODONG"],
"data": [
[38, "CAPITAL", "M31"]
]
};
var result = response.header.reduce(function(accum, v, i) {
accum[v] = response.data[0][i];
return accum;
}, {})
console.log(result)

When specifying a custom key in object, it turns it into an number

When I implement a string based number in a object as the key, when the object is rendered, its returned as a number instead of a string. This is throwing me off because my original array is reordered and then i want to generate an object based of a number which is an ID within the array row but the issue is, by default, javascript is reordering my object keys by numerical ordered list, instead of the order i tell it to be in.
var array = ['1','2','3'].reverse();
var obj = {};
$.each(array, (idx, item) => {
obj[item.toString()] = item;
});
console.log(array, obj);
return is
(3) ["3", "2", "1"] {1: "1", 2: "2", 3: "3"}
instead of
(3) ["3", "2", "1"] {3: "3", 2: "2", 1: "1"}
however, this works total fine with non numerical type characters, example below:
var array = ['hi','tom','how'].reverse();
var obj = {};
$.each(array, (idx, item) => {
obj[item.toString()] = item;
});
console.log(array, obj);
return as expected
(3) ["how", "tom", "hi"] {how: "how", tom: "tom", hi: "hi"}
by default, javascript is reordering my object keys by numerical ordered list, instead of the order i tell it to be in
Object properties are not ordered. There are various ways to get a list of or iterate over properties, but for most of them the order is implementation dependent. However, most current browsers will first iterate over numeric properties in ascending order and then over non-numeric properties in insertion order.
If you want guaranteed order then you should use a Map as explained in the other answer, because maps maintain insertion order, or keep using your array to define iteration order.
You can use Map to store properties in a specific order
var array = ['1','2','3'].reverse();
var obj = new Map;
array.forEach((item, idx) => {
obj.set(item.toString(), item);
});
console.log([...obj.entries()]);
array.forEach((item, idx) => {
console.log(obj.get(item))
});
console.log(obj);

Issue with creating an array from an object in javascript?

I have an object that I need to transform into an array. Here is the code I have already:
for (var key in categoryData[p]) { // categorydata is an object, the "p" is because this is taking place in a loop (array of objects)
if (categoryData[p].hasOwnProperty(key)) {
var objToArray = $.map(categoryData[p], function(value, key) {
return [value];
});
}
}
Right now, this is returning:
0 : value
1 : value
2 : value
I want it to return:
Key : Value
Key : Value
Key : Value
But I haven't found a way to do this with my data. Any direction would be greatly appreciated!
Edit: Adding more information:
I want to sort from the highest to lowest value. For clarification, I want the data to look like this:
(key) (object)
"ABC" : 8
"DEF" : 7
"GHI" : 5
I am putting it into an array to begin with because I can't sort the values when they're in an object (as far as I know).
My data is fairly complex, in a CSV file, but the idea of it is:
ABC, DEF, GHI
8 , 7 , 5
Associative arrays aren't a thing in javascript. You can either have arrays denoted by [] with 0 based numeric indices, or objects denoted by {} that can store key-value pairs. The latter construct can be used as replacement to associative arrays (ie add arbitrary keys and values to it), but they cannot be treated like arrays.
What you want in this case is what you already have - a key/value store, except it's called an object.
edit
If you just want to sort the data regardless of datatypes
You can split your object into multiple objects with a single key-value pair, then create an array from these objects and sort them any way you like using Array.sort(). Here's a quick example of splitting your provided data into objects:
var originalData = {
"ABC" : 8,
"DEF" : 7,
"GHI" : 5,
},
sortableArray = [];
for (key in originalData) {
sortableArray.push({
"key" : key,
"value" : originalData[key]
});
}
This creates a new object and appends it to our sortable [] array. To sort it according to its original value, you need to supply a comparator function that accesses the value property of the objects.
sortableArray.sort(function(a,b) {
return a.value - b.value;
});
This should return an array of objects ordered by the value property of each object in ascending order. Simply switch a and b around to get a descending order sort.
Hope this helps!
The best approach to sort your data is to map your object into an array to look like this:
[
{
"key": someKey
"value": someValue
},
{
"key": someOtherKey
"value": someOtherValue
},
//...
]
using this code:
var objToArray = $.map(categoryData[p], function(value, key) {
return {"key": key, "value": value};
});
And then sort it using this code:
objToArray.sort(function(a, b) {
// if the values are numbers (otherwise you have to change this to addapt to your dataType)
return b.value - a.value; // to sort from highest to lowest or a.value - b.value to sort from lowest to highest
});
And then you can use it like:
objToArray[0].key; // to get the key of the first item
objToArray[3].value; // to get the value of the 4-th item
// ...
You can loop through them as well (for(var i = 0; i < objToArray.length; i++)...).
In ES6, Object.entries(a).sort((a, b) => a[1] < b[1] )
This will give you something like this
[
["ABC", 8]
["DEF", 7]
["GHI", 5]
]
the .entries step gives you the list of pairs and the .sort step sorts them by their second value

Categories