Find a JSON object using multiple key / value pairs, then update that object attribute with another
Considering
sessionStorage.cart = "[
{"id":121,"name":"Pants","number":1,"specification":""},
{"id":121,"name":"Pants","number":2,"specification":""},
{"id":121,"name":"Pants","number":3,"specification":""}
]"
I would like to write a function that finds an object with ID 121, name Pants, number 2, so that I can update this object specification. So I would pass in the id, name, number and the required new BOM value and get the output of this:
sessionStorage.cart = "[
{"id":121,"name":"Pants","number":1,"specification":""},
{"id":121,"name":"Pants","number":2,"specification":"new value"},
{"id":121,"name":"Pants","number":3,"specification":""}
]"
I am really struggling to think about this through ... the guide is welcome!
source to share
Use this:
var cart = [
{
"id": 121,
"name": "Pants",
"number": 1,
"specification": ""
},
{
"id": 121,
"name": "Pants",
"number": 2,
"specification": ""
},
{
"id": 121,
"name": "Pants",
"number": 3,
"specification": ""
}
];
cart.forEach(function(entry) {
if (entry.id == 121 && entry.name == 'Pants' && entry.number == 2) {
entry.specification = 'new value';
}
});
console.log(cart);
source to share
Simple solution using Array.prototype.find
sessionStorage.cart.find(e =>
e.id === 121 &&
e.name === 'Pants' &&
e.number === 2
).specification = 'new value';
console.log(JSON.stringify(sessionStorage.cart, null, ' '));
Output
[
{
"id": 121,
"name": "Pants",
"number": 1,
"specification": ""
},
{
"id": 121,
"name": "Pants",
"number": 2,
"specification": "new value"
},
{
"id": 121,
"name": "Pants",
"number": 3,
"specification": ""
}
]
Note. This requires ES6.
source to share
You might want to try this code:
function update(oldValues, newValues, keyToCompare) {
var keyToCompareLen = keyToCompare.length;
var result = [];
oldValues.forEach(function(oldValue){
newValues.forEach(function(newValue){
var cnt = 0;
keyToCompare.forEach(function(key){
if(newValue[key] == oldValue[key]) {
++cnt;
}
});
if(cnt == keyToCompareLen) {
oldValue = $.extend(true, {}, oldValue, newValue);
}
});
result.push(oldValue);
});
return result;
}
var result = update([
{"id":121,"name":"Pants","number":1,"specification":""},
{"id":121,"name":"Pants","number":2,"specification":""},
{"id":121,"name":"Pants","number":3,"specification":""}
], [
{"id":121,"name":"Pants","number":2,"specification":"test"}
], [
"id",
"name",
"number"
]);
console.log(result);
Note. You need to include jquery library. You can also run the code here https://fiddle.jshell.net/b17fx6qk/1/
source to share
Iterating through an array can be inefficient. For performance, you can harden all of your index values ββand use them to store your objects in a hashmap for fast lookups. Something like:
function cartItem() {
this.id;
this.name;
this.number;
this.specification;
}
CartItem.hash = function(id, name, number) {
return [id, name, number].join('|');
};
cartItem.prototype.toHash = function() {
return CartItem.hash(this.id, this.name, this.number);
};
var cartMap = cart.reduce(function(map, item) {
var key = item.toHash();
map[key] = item;
}, { });
Then you can (very quickly) look up the element by its hash:
cartMap[CartItem.hash(id, name, number)];
source to share
Try this. Just match and update
$(document).ready(function() {
var o = [];
o.id = 121;
o.name = "Pants";
o.number = 2;
updateVal(o);
});
function updateVal(o) {
var cart = [{
"id": 121,
"name": "Pants",
"number": 1,
"specification": ""
}, {
"id": 121,
"name": "Pants",
"number": 2,
"specification": ""
}, {
"id": 121,
"name": "Pants",
"number": 3,
"specification": ""
}];
$.each(cart, function(a, b) {
if (b.id == o.id && b.name == o.name && b.number == o.number) {
b.specification = "new value";
}
});
alert("value updated. specification:" + cart[1].specification);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
source to share