change the value of object using loop [duplicate] - javascript

This question already has answers here:
JavaScript Object Mirroring/One-way Property Syncing
(2 answers)
Closed 7 years ago.
I have an object as,
var obj = [
{
"name": "a",
"value": "1"
},
{
"name": "b",
"value": "2"
},
{
"name": "c",
"value": "3"
}
]
I have a large object with more than 50 values.
how can I change the value key using its name
and what is the best looping technique for this.
I tried for loop for this like,
for(i = 0; i < obj.length; i++) {
if(obj[i].name == "b") {
// some other functionality
obj[i].value = "some_value";
}
}
But, it takes long time and sometimes for loop goes for next turn before if condition is executed.
Please explain how to solve it or is there any other looping technique

you can use forEach , but as far your hitting the performance its not best ,
you can use map but native for loop is fastest compared to map too
https://jsperf.com/native-map-versus-array-looping
Map , which runs on the each item of the array and return the new array
obj.map(function(item){
if(item.name === "b"){
item.value = "some_value"
}
return item;
})

You can try this :
$(document).ready(function(){
var obj = [
{
"name": "a",
"value": "1"
},
{
"name": "b",
"value": "2"
},
{
"name": "c",
"value": "3"
}
]
for(i = 0; i < obj.length; i++) {
(function(i){
if(obj[i].name === "b") {
console.log(obj[i].name);
// some other functionality
obj[i].value = "some_value";
}
})(i);
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

I think what you had was quite ok. As one of the comments stated, there was a mistake in the IF-statement which prevented it from being triggered.
I am not sure theres a faster way to proces the JSON object than the way you did. Here's a JSFiddle with some small changes.
function ReplaceValue(name, val) {
for (i = 0; i < obj.length; i++) {
if (obj[i].name == name) {
// some other functionality
obj[i].value = val;
break;
}
}
alert(JSON.stringify(obj, null, 2));
}

Map is your friend!
var obj = [
{ "name": "a", "value": "1" },
{ "name": "b", "value": "2" },
{ "name": "c", "value": "3" }
];
var newObj = obj.map((elm) => {
if(elm.name === "b") elm.value = "some value";
return elm;
});
Is this something like what you were looking for?

In lodash you can do something like this:
`
var obj = [
{
"name": "a",
"value": "1"
},
{
"name": "b",
"value": "2"
},
{
"name": "c",
"value": "3"
}
];
_.transform(arr, function(r, n){
if(n.name == 'b'){
r.push({name: n.name, value: 'some value'})}
else{
r.push(n)
}
})
`

Related

Evaluating key values in multi-dimensional object

I have a multi-dimensional object that looks like this:
{
"links": [{"source":"58","target":"john","total":"95"},
{"source":"60","target":"mark","total":"80"}],
"nodes":
[{"name":"john"}, {"name":"mark"}, {"name":"rose"}]
}
I am trying to evaluate the value of "total" in "links." I can do this in a one-dimensional array, like this:
for (var i = 0; i < data.length; i++) {
for (var key in data[i]) {
if (!isNaN(data[i][key])) {
data[i][key] = +data[i][key];
}
}
};
But I have not been able to figure out how to do this in two-dimensions (especially calling the value of key "total" by name).
Can anybody set me on the right track? Thank you!
Starting from the principle that the structure of your array is this, you can to iterate the keys and the values:
var obj = {
"links": [{"source":"58","target":"john","total":"95"},
{"source":"60","target":"mark","total":"80"}],
"nodes":
[{"name":"john"}, {"name":"mark"}, {"name":"rose"}]
};
for (var key in obj){
obj[key].forEach(function(item){
for(var subkey in item){
if (subkey == 'total')
console.log(item[subkey]);
};
});
};
You can get total using reduce
check this snippet
var obj = {
"links": [{
"source": "58",
"target": "john",
"total": "95"
}, {
"source": "60",
"target": "mark",
"total": "80"
}, {
"source": "60",
"target": "mark",
"total": "80"
}],
"nodes": [{
"name": "john"
}, {
"name": "mark"
}, {
"name": "rose"
}]
}
var links = obj.links;
var sum = links.map(el => el.total).reduce(function(prev, curr) {
return parseInt(prev, 10) + parseInt(curr, 10);
});
console.log(sum);
Hope it helps
Extract the values from the array, convert them to numbers and add them up.
Array.prototype.map() and Array.prototype.reduce() are pretty helpful here:
var data = {"links":[{"source":"58","target":"john","total":"95"},{"source":"60","target":"mark","total":"80"}], "nodes":[{"name":"john"}, {"name":"mark"}, {"name":"rose"}]};
var sum = data.links.map(function(link) {
return +link.total;
}).reduce(function(a, b) {
return a + b;
});
console.log(sum);

Javascript, remove property from one of two similar objects in array

Let's assume we have this data set:
var array = [
{
"name": "a",
"group": "a"
},
{
"name": "a",
"group": "a"
},{
"name": "b",
"group": "b"
},
{
"name": "b",
"group": "b"
},
{
"name": "c"
}
];
and I want to loop through the array to see if there are two objects have the same group value, then remove the second of them.
for(var i = 0 ; i<array.length;i++){
var a = array[i];
for(var j = 0; j< array.length;j++){
if(array[j].group == a.group){
var b = array[j];
// I need code here to remove property "group" from the variable b only
break;
}
}
}
the final results I want are:
var array2 = [
{
"name": "a",
"group": "a"
},
{
"name": "a"
},{
"name": "b",
"group": "b"
},
{
"name": "b"
},{
"name":"c"
}
];
NOTE: I tried delete array[j].group but it caused to remove both group property from both equal objects. How can I solve that?
You shouldn't compare same items, just shift indexes in inner loop:
var array = [{"name": "a", "group": "a"},
{"name": "a", "group": "a"},
{"name": "b", "group": "b"},
{"name": "b", "group": "b"},
{"name": "c"}];
for(var i = 0 ; i < array.length - 1; i++){
var a = array[i];
if(!a.group){
continue;
}
for(var j = i+1; j < array.length; j++){
var b = array[j];
if(b.group === a.group){
delete b.group;
}
}
}
console.log(array)
You can try this:
var tmpObj = {};
tmpObj.name = array[j].name;
array.splice(j, 1, tmpObj);
It should remove the element with index j and add new object with only name.
Just store all the group values you already have seen, and remove them if you see them again. Moreover, this will save you a loop.
var myArray = [...];
var existingGroups = [];
myArray.forEach(function(item){
if(item.group){
if(existingGroups.indexOf(item.group) === -1)
existingGroups.push(item.group);
else
delete item.group;
}
});
I'd go with a different approach:
Little explanation of the if condition:
array.slice(0, i): we take only the previous elements of the array.
.filter(v => v.group === val.group) we see if they have the same value for property group.
.length === 0) If there is at least one element with the same value of group, we do not enter the if and return only the name, otherwise we return the value itself
var array = [{"name": "a", "group": "a"},
{"name": "a", "group": "a"},
{"name": "b", "group": "b"},
{"name": "b", "group": "b"},
{"name": "c"}];
array = array.map((val, i) => {
if (array.slice(0, i).filter(v => v.group === val.group).length === 0) {
return val;
}
return {name: val.name};
})
console.log(array)
Here is a simple code which might help:
var groups = {};
array.forEach(function(o) {
if (groups[o.group]) {
delete o.group;
} else {
groups[o.group] = true;
}
})
You can also use more functional approach but you will need an additional utility library or have to implement some of the methods yourself.
var groups = array.map(function(o) { return o.group; }).unique();
groups
.map(function(group) {
return array.filter(function(o) { o.group == group }).slice(1);
})
.flatten()
.forEach(function(o) { delete o.group });
flatten & unique are not included in the JavaScript spec.
You don't need imbricated loops to do this. You can use .forEach() while keeping track of the groups that have been encountered so far. This can be done by using either the optional thisArg parameter or an explicit variable.
For instance:
var array = [
{ "name": "a", "group": "a" },
{ "name": "a", "group": "a" },
{ "name": "b", "group": "b" },
{ "name": "b", "group": "b" },
{ "name": "c" }
];
var grp = {};
array.forEach(function(o) {
grp[o.group] ? delete o.group : grp[o.group] = true;
});
console.log(array);

splice array base on property value

$scope.myJson = [{
"id": "1",
"name": "banana",
"price": 12,
"qty": 3,
}, {
"id": "2",
"name": "watermelon",
"price": 12.9,
"qty": 4,
}];
for(i = 0; i < $scope.myJson.length; i++) {
if($scope.myJson[i]._id == '2'){
//what to do here?
//then save back to localstorage
}
}
I'm using localstorage so I have to find array and splice it. I don't know how to proceed.
Splice is the worst option in terms of performance.
Yet in your case you would need to do:
$scope.myJson.splice(i,1);
See performance comparison here: https://jsperf.com/splice-vs-filter
I would at least do a filter:
$scope.myJson = $scope.myJson.filter(function(obj) {
return (obj.id !== '2');
}) ;
Just iterate through the array, search for the desired property value and splice the array.
function spliced(array, value) {
var arr = array.slice(0);
array.forEach(function (obj) {
if (obj.hasOwnProperty('id')) {
if (obj['id'] == value ) {
arr.splice(arr.indexOf(obj),1);
}
}
});
return arr;
}
console.log( spliced(arr, 1) )

Removing Duplicate object from array in jquery code not working

This is my array in jquery , which contains duplicate objects/elements :
[{
"name": "hello",
"label": "world"
}, {
"name": "abc",
"label": "xyz"
}, {
"name": "hello",
"label": "world"
}]
I am using the following piece of code to remove duplicate elements but it not working the duplicate elements are not removed.
var result = [];
$.each(subservices, function (i, e) {
if ($.inArray(e, result) == -1)
result.push(e);
});
alert(JSON.stringify(result));
Function $.inArray works fine for simple types (e.g. number or string), but for complex types it does not produce the correct result, because it tries to match by reference. Instead of using inArray in your loop you can search the array using function grep:
var subservices = [{
"name": "hello",
"label": "world"
}, {
"name": "abc",
"label": "xyz"
}, {
"name": "hello",
"label": "world"
}
];
var result = [];
$.each(subservices, function (i, e) {
var matchingItems = $.grep(result, function (item) {
return item.name === e.name && item.label === e.label;
});
if (matchingItems.length === 0){
result.push(e);
}
});
//displays result [{"name":"hello","label":"world"},{"name":"abc","label":"xyz"}]
alert(JSON.stringify(result));
Here is a working jsFiddle
You need to filter array by unique name/value. Here is some pure JS solution:
var data = [{
"name": "hello",
"label": "world"
}, {
"name": "abc",
"label": "xyz"
}, {
"name": "hello",
"label": "world"
}];
var result = data.filter(function(el, i, x) {
return x.some(function(obj, j) {
return obj.name === el.name && (x = j);
}) && i == x;
});
alert(JSON.stringify(result, null, 4));
This is because these two objects are distinct, even though all the attributes inside are the same. You can see this from:
console.log(result[0] === result[2]);
which results in false.
Instead, you need to iterate through your array based on a unique identifier, such as name & label as such:
for(var i = 0, i < results.length; i++) {
if (result[i].name === ... && result[i].label === ...) {
index = i;
break;
}
}
to check if your item is unique.

programmatically add object properties of arrays

[
{
"uId": "2",
"tabId": 1,
"tabName": "Main",
"points": "10"
},
{
"uId": "3",
"tabId": 2,
"tabName": "Photography",
"points": "20"
}
]
how can I insert into specified array by inspecting its properties values? says I want to add a assoc object into uId = 3, how can I do that? or it's not possible technically?
This is also possible using array.map (Added to the ECMA-262 standard in the 5th edition):
array.map(function(i){
if(i.uId == 3) i['newprop'] = 'newValue';
});
Example Here.
Update: It could be an array
if(i.uId == 3) i['newprop'] = ['newvalue1', 'newvalue2'];
Example2 Here.
They look like JSON data , so json_decode() to an array , search for the UId value and then add the corresponding assoc value and after the end finally wrap them up using json_encode()
foreach($array as $k=>&$arr)
{
if($arr->{'uId'}==2)
{
$arr->{'somecol'}="Hey";
}
}
echo json_encode($array,JSON_PRETTY_PRINT);
OUTPUT :
[
{
"uId": "2",
"tabId": 1,
"tabName": "Main",
"points": "10",
"somecol": "Hey"
},
{
"uId": "3",
"tabId": 2,
"tabName": "Photography",
"points": "20"
}
]
var array = [
{
"uId": "2",
"tabId": 1,
"tabName": "Main",
"points": "10"
},
{
"uId": "3",
"tabId": 2,
"tabName": "Photography",
"points": "20"
}
];
for ( var i = 0; i < array.length; i++ ) {
if ( array[i].uId == 3) {
array[i].someProp = "Hello";
break; // remove this line for multiple updates
}
}
Or you can make a function like this:
function getMatch(data, uid) {
for ( var i = 0; i < data.length; i++ ) {
if ( data[i].uId == 3) {
return data[i];
}
}
}
and use it like this:
getMatch(array, 3).someproperty = 4;
You can use the map function, which executes a function on each element of an array
a.map(function(el) {
if (el.uId == 3) {
el.prop = "value";
}
});
Or you can use the filter function.
// Get the array of object which match the condition
var matches = a.filter(function(x) { return x.uId == 3 });
if (matches.length > 0) {
matches[0].prop = "value";
}

Categories

Resources