Find duplicate values inside array of objects - javascript

What is the best way in JavaScript to go over array of object and check if an certain value already exist in one of the property of the array objects?
For example: I have array of objects as follow:
[{name:"team1",members:3},{name:"bestteam",members:4}]
Now I want to add a new object but I want to check that this object property "name" do not exist in the array before adding it

Try this
function checkIfNameExists(arr, newName) {
return arr.some(function(e) {
return e.name === newName;
});
}
where arr is your array and newName is the name to check.
You could also make it less ad hoc by passing the property to compare as a parameter, like so
function checkIfNameExists(arr, prop, newVal) {
return arr.some(function(e) {
return e[prop] ? e[prop] === newVal : false;
});
}

assuming you say an object equals an object if and only if they have the exact same elements and values for each element:
var map = {};
for (var i = 0; i < arr.length; i++) {
var index = JSON.stringify(arr[i]);
if (!map[index]) {
map[index] = 1;
} else {
map[index]++;
}
}
for (var key in map) {
if (map[key] > 1) {
console.log ('duplicate found for:');
console.log (JSON.parse (key));
}
}
simply define an array "arr" with some objects and check it out

You can iterate over the array and iterate over the keys of the array and check if some properties have the wanted value.
var data = [{ prop1: 'one', prop2: 'two' }, { prop3: 'three', prop4: 'four' }];
function find(v, data) {
data.forEach(function (a, i) {
Object.keys(a).forEach(function (k) {
if (a[k] === v) {
document.write(v + ' found in [' + i + '].' + k);
}
});
});
}
find('three', data);

You can use simple loops. Here is function which should help you to find out if key value is in array.
function keyExist(value, array) {
for(var i in array) {
for(var k in array[i])
if(array[i][k] === value) {
console.log(value + ' is in array!');
return true;
}
}
return false;
}
As for you example you can change second loop
for(var k in array[i])
if(k === value) { return true; }
to
if(array[i].name === value) { return true; }

I have no time to respond but here from my previous code maybe some will optimize it...
function JSONRemoveDuplicates(JSONDATA) {
var uniqueNames = [];
$.each(JSONDATA, function (i, el) {
if (!existInJSON(uniqueNames, el) > 0) { uniqueNames.push(el); }
});
return uniqueNames;
}
function existInJSON(jsondata, el) {
var ret = 0;
$(jsondata).each(function (index, data) {
if (data.id == el.id)
ret++;
})
return ret > 0;
}

Related

How to add object name to table columns

I am receiving JSON array, flattening it to display it as a table, but this logic I am using has a flaw, if my object have same column name it will ignore it and will only add first column it finds.
Problem I am trying to solve
Display nested objects into a flat table
Problem I am stuck at
I want to add object's name to column header, which is not happening at the moment.
I think problem is here
function flattenRecord(result, rec) {
return Object.keys(rec).reduce(function(result, key) {
var value = rec[key];
if (value && typeof value === 'object')
flattenRecord(result, value);
else
result[key] = value; // How to add key here so that it will be added to column header ?
return result;
}, result);
}
Complete Code and Working Example
https://jsfiddle.net/1tsu6xt9/14/
I have fixed the issue, I had to change logic of flattening JSON as suspected,
Changed FlattenRecord method to following,
function flattenRecord2(data) {
var result = {};
function recurse(cur, prop) {
if (Object(cur) !== cur) {
result[prop] = cur;
} else if (Array.isArray(cur)) {
for (var i = 0, l = cur.length; i < l; i++)
recurse(cur[i], prop);
//if (l == 0)
//result[prop] = [];
} else {
var isEmpty = true;
for (var p in cur) {
isEmpty = false;
recurse(cur[p], prop ? prop + "." + p : p);
}
if (isEmpty && prop)
result[prop] = {};
}
}
recurse(data, "");
return result;
}
and following line too,
var rows = testData.reduce(function(rows, row) {
return appendRow(rows, flattenRecord2(row));
}, []);

find value pair in json object using key element

With reference to question posted here use jQuery's find() on JSON object
I have json object in which i'd like to search value of the element if i passed respective key element to it
Json:
{"RESPONSE":{"#xmlns":"","CODE":"0","SECODE":"0","TXNID":"17527","LASTBALANCE":"-12078.8","SURCHARGE":"2","CUSTOMERDETAILS":{"NAME":"Mr.ABC"}}}
I want to retrieve value Mr.ABC when i passed Name as a key to my function
Code:
console.log(getObjects(ContextObj, 'Name'));
function getObjects(obj, key) {
var objects = [];
for (var i in obj) {
if (!obj.hasOwnProperty(i)) continue;
if (i == key) {
objects.push(obj);
}
}
return objects;
}
It gives output now as
[ ]
Try this:
var data = {"RESPONSE":{"#xmlns":"","CODE":"0","SECODE":"0","TXNID":"17527","LASTBALANCE":"-12078.8","SURCHARGE":"2","CUSTOMERDETAILS":{"NAME":"Mr.ABC"}}};
function find_value(key, inner_key) {
var value = "";
$.each(data.RESPONSE, function (i, k) {
console.log(i, key, i == key)
if (i == key) {
value = k;
return false;
}
});
if (inner_key) {
if (value[inner_key]) {
value = value[inner_key];
}
}
return value;
}
Calling function:
find_value("LASTBALANCE");
find_value("CUSTOMERDETAILS", "NAME");
See DEMO here.
You need to call your code recursive for nested json keys like,
var s={"RESPONSE":{"#xmlns":"","CODE":"0","SECODE":"0","TXNID":"17527","LASTBALANCE":"-12078.8","SURCHARGE":"2","CUSTOMERDETAILS":{"NAME":"Mr.ABC"}}};
console.log(getObjects(s, 'NAME'));
console.log(getObjects(s, 'LASTBALANCE'));
function getObjects(obj, key) {
var objects = [];
for (var i in obj) {
if(typeof obj[i] == 'object'){
return getObjects(obj[i], key); // if it is an object then find the key recursively.
}
if (!obj.hasOwnProperty(i)) continue;
if (i == key) {
return obj[key];
}
}
return '';
}
Working DEMO

Access nested objects via array of property names

Say I have an object like this (simplified):
var options = {
boxes: {
size: {
x: 15,
y: 18
},
shadow: {
[...]
}
};
And I have an array of names:
var names = ['boxes', 'size', 'x'];
What is an easy way to get/set a value inside the object according to the array, in this example it would be:
options.boxes.size.x = somevalue;
Any ideas?
There's no easy, built-in method for doing this. You'd have to write your own method:
function getPath(obj, props) {
for(var i = 0; i < props.length; i++) {
if (props[i] in obj) {
obj = obj[props[i]];
} else {
return; // not found
}
}
return obj;
}
function setPath(obj, value, props) {
for(var i = 0; i < props.length - 1; i++) {
if (props[i] in obj) {
obj = obj[props[i]];
} else {
return; // not found
}
}
obj[props[i]] = value;
}
alert(getPath(options, names)); // 15
setPath(options, 25, names);
alert(getPath(options, names)); // 25
Just use a loop that iterates the names and grabs the next nested object for the current name. Either a falsey value or the end of the array should halt the loop.
var obj = options;
var i = 0;
while (obj && i < names.length)
obj = obj[names[i++]];
Or simply use .reduce()
names.reduce(function(obj, name) {
return obj && obj[name];
}, options);
And of course you can name and reuse the function if you prefer.
function toPropertyIn(obj, name) {
return obj && obj[name];
}
names.reduce(toPropertyIn, options);
To make a getter/setter:
function nestedProp(obj, names, value) {
if (arguments.length > 1)
var setProp = names.pop();
var res = names.reduce(function(obj, name) {
return obj && obj[name];
}, options);
if (res && setProp !== undefined)
res[setProp] = value;
else
return res;
}
nestedProp(options, names, "foo"); // to set
var val = nestedProp(options, names); // to get

return key value pair from object whose key matches certain condition with javascript and underscore

var obj = {
"M_18-24":413109,
"F_18-24":366159,
"F_25-34":265007,
"U_25-34":1214,
"U_35-44":732
}
I want to return an object with key value pairs whose keys start with either "M" or "F". So the final object would look like
var obj = {
"M_18-24":413109,
"F_18-24":366159,
"F_25-34":265007
}
I've tried things like _.filter(obj, function(v,k) { return /^[MF]/.test(k) })...
this will do the trick:
function filte_obj_FM (inp)
{
var ret = {};
for ( var k in inp)
{
if ( k[0] == "M" || k[0] == "F" )
{
ret[k] = inp[k];
}
}
return ret;
}
see console output (F12 +-> see console) here: http://jsfiddle.net/vH3ym/2/
You can try
for (var prop in obj) { console.log(prop) }
It will give you the corresponding properties, then you can add your logic like
if(prop.indexOf('M'))
This should work:
var obj = {
"M_18-24":413109,
"F_18-24":366159,
"F_25-34":265007,
"U_25-34":1214,
"U_35-44":732
}
var filtered = {}
for(var key in obj) {
if(key[0] === "M" || key[0] === "F"){
filtered[key] = obj[key]
}
}
Another version this time using reduce:
// create a new underscore function that will return the properties from an object that pass a given predicate
_.mixin({ filterProperties: function(obj, predicate){
return _.reduce(obj, function(memo, value, key){
if( predicate(key) ){
memo[key] = value;
}
return memo;
}, {});
}});
// A couple of predicates that we can use when calling the new function
function isMale(key){
return key[0] == 'M';
}
function isFemale(key){
return key[0] == 'F';
}
// and finally getting the data we want:
var males = _.filterProperties( obj, isMale );
var females = _.filterProperties( obj, isFemale );
Here's my solution:
_.filter(_.keys(obj), function(key) {
return key.match(/U/);
}).forEach(function(kv) {
delete obj[kv];
});
I think all of yours are good and I voted them up. Thanks!

Set value in JSON by a path using lodash or underscore

I wanna set the value in a JSON using a path string like this "a.0.b" for a JSON that looks like this:
{
a: [
{
b: 'c'
}
]
}
I came up with this solution but I wonder if there is a simpler way to write this:
function setValue(path, value, json) {
var keys = path.split('.');
_.reduce(keys, function(obj, key, i) {
if (i === keys.length - 1) {
obj[key] = value;
} else {
return obj[key];
}
}, json);
}
so calling setValue('a.0.b', 'd', {a:[{b:'c'}]}) would change the json to {a:[{b:'d'}]}
Here's a solution. I benchmarked the two possible solutions and it seems looping over object and path is faster than using the reduce function. See the JSPerf tests here: http://jsperf.com/set-value-in-json-by-a-path-using-lodash-or-underscore
function setValue(path, val, obj) {
var fields = path.split('.');
var result = obj;
for (var i = 0, n = fields.length; i < n && result !== undefined; i++) {
var field = fields[i];
if (i === n - 1) {
result[field] = val;
} else {
if (typeof result[field] === 'undefined' || !_.isObject(result[field])) {
result[field] = {};
}
result = result[field];
}
}
}

Categories

Resources