Updating values of an object within array - javascript

I have an array of objects that looks like this:
[
{
"id": 123,
"timeStamp": "\"2019-07-08T20:36:41.580Z\"",
"data": [1, 2, 3]
},
{
"id": 234,
"timeStamp": "\"2019-07-08T20:37:12.472Z\"",
"data": ["Apples", "Oranges"]
}
]
I want to update the value of a particular property of an object within the array but also want to make sure that I return the result in a new array.
How do I do this without running through some type of a loop e.g. for loop?
Say, I want to update the data property of the second object and add Bananas to it.

If you want the result to be a new array, you'll first have to clone the array. This can be more complicated than you might imagine (depending on how deeply you wish to clone things). One way is to use JSON stringify...
Bear in mind that the JSON trick is effectively doing a loop behind the scenes. Inevitable if you want to copy the array, really.
To find the object by ID use Array.find()
let original = [
{
"id": 123,
"timeStamp": "\"2019-07-08T20:36:41.580Z\"",
"data": [1, 2, 3]
},
{
"id": 234,
"timeStamp": "\"2019-07-08T20:37:12.472Z\"",
"data": ["Apples", "Oranges"]
}
]
let copy = JSON.parse(JSON.stringify(original));
copy.find(obj => obj.id === 234).data.push("Bananas");
console.log(copy);

Something like this would do the trick:
let arr = [
{
"id": 123,
"timeStamp": "\"2019-07-08T20:36:41.580Z\"",
"data": [1, 2, 3]
},
{
"id": 234,
"timeStamp": "\"2019-07-08T20:37:12.472Z\"",
"data": ["Apples", "Oranges"]
}
]
arr[1]['data'] = [...arr[1]['data'], 'Bananas']
console.log(arr)

For your example: you can do something like this: say your array of object is saved in test variable
test[1].data.push("Bananas")

Related

How to get JSON entry from returned objects

I got JSON data, like:
{
"id": 1,
"active": true,
"dependency": [
{ "id": 2 }
{ "id": 3 }
]
},
{
"id": 2,
"active": true
},
{
"id": 3,
"active": true
}
I want to retrieve the "active" value for each dependency in the id 1 object. So far I used a forEach to get those dependency.
thisElement.dependency.forEach(function(id) {
console.log(id)
}
Which returns id 2 and id 3 as objects. Is there a way to use id.active straight away? By using only one loop? Because the result so far are objects without any connection to the related JSON data. Would it require to loop through the whole JSON data to retrieve those values?
The most efficient thing to to is create a hashmap with an Object or Map first so you only need to iterate the array once to find dependency related values.
You could do it by using Array#find() to search whole array each time but that is far more time complexity than the o(1) object lookup
const activeMap = new Map(data.map(obj => [obj.id, obj.active]))
data[0].dependency.forEach(({id}) => console.log(id ,' active: ' , activeMap.get(id)))
<script>
const data =
[
{
"id": 1,
"active": true,
"dependency": [
{"id": 2 },
{"id": 3}
]
},
{
"id": 2,
"active": false
},
{
"id": 3,
"active": true
}
]
</script>

Get the difference between two arrays

I need to get only the difference between two arrays
I tried:
let arr1 = {
"data": [{
"id": "EID_Floss",
"name": "Floss",
"te": "dd"
}]
}
let arr2 = {
"data": [{
"id": "EID_Floss",
"name": "Floss"
}]
}
JSON.stringify(arr2.data.filter((x) => !arr1.data.includes(x)))
Result:
[{
"id": "EID_Floss",
"name": "Floss"
}]
How to get only this:
[{
"te": "dd"
}]
Look at this simpler example:
arr1 = ["foo", "bar"];
arr2 = ["foo", "bar", "foobar"];
arr3 = arr2.filter((x) => !arr1.includes(x));
console.log(arr3);
This does exactly what you exect and the output is:
["foobar"]
The problem with your example, is that the arrays in arr1.data and arr2.data contain objects. You are comparing the object
{
"id": "EID_Floss",
"name": "Floss",
"te": "dd"
}
from arr1 with the object
{
"id": "EID_Floss",
"name": "Floss"
}
from arr2. Since these are not equal, your filter does not remove the object from the array.
Note that this is an all or nothing operation since you are filtering the array of objects. Instead, it sounds like you want to filter the keys in each object. So you need to use Object.keys() or Object.values() to iterate over the contents of the objects.

Is there a shorter/more efficient way to use the spread operator in javascript to update a key's value?

I recently got interested on using the spread operator syntax, so I tried some examples, I have this example of array:
var entities = [
{
"id": 1,
"age": 33,
"hobby": "games"
},
{
"id": 2,
"age": 28,
"hobby": "chess"
},
{
"id": 3,
"age": 21,
"hobby": "comics"
},
{
"age": 23,
"hobby": "games"
}
]
Then, to update all hobbies at "once" I do the following:
entities.forEach(function(entity, index) {
this[index] = {...entity, hobby: "Some String to update all hobbies"};
}, entities);
console.log(entities)
Which works but I was wondering if there's a more efficient or shorter way to achieve it while using the spread operator. Any suggestions?
EDIT:
forEach is not necessary for me, or even do it in that way, I was curious on whether the spread syntax could be used (or not) to update nested values
The spread operator doesn't really help when you're updating the list, like you do in your example. It's easier to just update the property of each object:
var entities = [ { "id": 1, "age": 33, "hobby": "games" }, { "id": 2, "age": 28, "hobby": "chess" }, { "id": 3, "age": 21, "hobby": "comics" }, { "age": 23, "hobby": "games" } ]
entities.forEach(entity => {
entity.hobby = "Some String to update all hobbies";
});
console.log(entities)
The spread operator is useful if you want to create copies of objects, like you might want to do in a .map:
var entities = [ { "id": 1, "age": 33, "hobby": "games" }, { "id": 2, "age": 28, "hobby": "chess" }, { "id": 3, "age": 21, "hobby": "comics" }, { "age": 23, "hobby": "games" } ]
const newEntities = entities.map(entity =>
({...entity, hobby: "Some String to update all hobbies"})
);
console.log(newEntities)
The spread operator will iterate over all keys in the object to copy them and their values into the new object. If you want more efficiency, don't use the spread operator. Just assign directly to each object as you iterate over the list:
entity.hobby = "Some String to update all hobbies"
Note that this modifies the object in the existing array. So you don't need to assign this[index]. Alternatively, you can use map() instead of foreach() to return a new array that is created from the existing array.
Not sure if spread operator is really needed for what you are doing?
You can also look into this link for some interesting usage of the spread, Array.from and rest operator.
More into just spread operator here.
If you are looking for a fancier/smaller way to write this, here's two, one that uses uses .map and spread to return a copy of entities, and another that uses .forEach and updates the same array entities:
const COMMON_HOBBY = 'Coding';
let entities = [{
"id": 1,
"age": 33,
"hobby": "games"
},
{
"id": 2,
"age": 28,
"hobby": "chess"
}];
// To assign to new array (copy)
let output = entities.map((entity) => ({...entity, hobby: COMMON_HOBBY }));
console.log(output);
// Mutate /edit same array entities
entities.forEach((entity) => entity.hobby = COMMON_HOBBY );
console.log(entities);

Formatting JSON for Angular data binding

when my ajax call completes an array of json is returned
for my angular data binding to work perfectly, i need to merge all values in to a single JSON file. I have tried $.extend(), it's giving following output
Need a solution for this
for example if my response looks like this:
[0:"{'test':'test'}", 1:"{'test':'test'}", 2:"{'test':'test'}",3: "{'test':'test'}"];
the output i need is :
{ test':'test', 'test':'test', 'test':'test', 'test':'test' }
Edit:
The final value will be associated to the ng-model automatically.
desired output example:
{
"unique_id": 172,
"portfolio": "DIGITAL",
"bus_unit": "dummy",
"project_phase": "",
"test_phase": "SIT",
"project": "Google",
"golivedate": "03/09/2016",
"performance": "Green",
"summary": "jgnbfklgnflknflk",
"last_updated": "",
"risks_issues": "gfmngfnfglkj",
"project_start": "03/16/2016",
"batchLast_run": "",
"custom_project": "1",
"test_execution_id": 5456,
"unique_id": 172,
"test_execution_id": 5456,
"pass": 8,
"fail": 8,
"blocked": 8,
"in_progress": 8,
"no_run": 8,
"not_available": 0,
"total": 8
}
From what I understand you are trying to convert array of Json data into one singel json data. So you have array of values but you would want all of them in one variable. Try this
var testData = ["{'test':'test'}", "{'test':'test'}", "{'test':'test'}", "{'test':'test'}"];
var finalData ="";
$.each(testData,function(index,value){
finalData += value +',';
});
finalData = finalData.replace(/\},\{/g,',').slice(0, -1);
document.write(finalData);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Map just applies the function to every element in the array.
var arrayOfJSON = ...
var arrayOfObjects = arrayOfJSON.map(function (jsonString){
return JSON.parse(jsonString)
})
var jsonStringWithAllObjects = JSON.stringify(arrayOfObjects)
If you use underscore.js then can easily
like:
var list = [{"test1": "test1"}, {"test2": "test2"}, {"test3": "test3"}];
var newList = _.extend.apply(null,[{}].concat(list));
then output will be
{ test1: "test1", test2: "test2", test3: "test3" }
Iterate over the array, convert every value to a JSON object, concatenate and then convert to a string back.
If you need fo this more times, you probably should make this a function.

How to sort an array of objects in ascending order of number?

I have an array of objects like the following :
var array = {
"112" : {
"id": "3",
"name": "raj"
},
"334" : {
"id": "2",
"name": "john"
},
"222" : {
"id": "5",
"name": "kelvin"
}
}
Now i want to sort the array in ascending order of id and then restore it in array. I tried using sort() but could not do it. Please help how to do so that when i display the data from the array it comes sorted.
Assuming you meant your code to be an array of objects, ie:
var unsortedArray = [
{ id: 3, name: "raj" },
{ id: 2, name: "john" },
{ id: 5, name: "kelvin" }
];
Then you would be able to sort by id by passing a function to Array.sort() that compares id's:
var sortedArray = unsortedArray.sort(function(a, b) {
return a.id - b.id
});
As others have pointed out, what you have is an object containing objects, not an array.
var array = {
"112" : {
"id": "3",
"name": "raj"
},
"334" : {
"id": "2",
"name": "john"
},
"222" : {
"id": "5",
"name": "kelvin"
}
}
var sortedObject = Array.prototype.sort.apply(array);
result:
{
"112": {
"id": "3",
"name": "raj"
},
"222": {
"id": "5",
"name": "kelvin"
},
"334": {
"id": "2",
"name": "john"
}
}
That isn't an array, it is an object (or would it if it wasn't for the syntax errors (= should be :)). It doesn't have an order.
You could use an array instead (making the current property names a value of a key on the subobjects).
Alternatively, you could use a for loop to build an array of the key names, then sort that and use it as a basis for accessing the object in order.
JavaScript objects are unordered by definition. The language specification doesn't even guarantee that, if you iterate over the properties of an object twice in succession, they'll come out in the same order the second time.
If you need things to be ordered, use an array and the Array.prototype.sort method.
That is an object but you can sort an array ilke this:
Working Demo: http://jsfiddle.net/BF8LV/2/
Hope this help,
code
function sortAscending(data_A, data_B)
{
return (data_A - data_B);
}
var array =[ 9, 10, 21, 46, 19, 11]
array.sort(sortAscending)
alert(array);​
Not many people knows that Array.sort can be used on other kinds of objects, but they must have a length property:
array.length = 334;
Array.prototype.sort.call(array, function(a, b) {return a.id - b.id;});
Unfortunately, this doesn't work well if your "array" is full of "holes" like yours.

Categories

Resources