Javascript | Search in an array of JSON by JSONs specific key value - javascript

I need search in an array of JSON objects if a key with especific id value exists. If exists, return it, if not return -1 or whatever
var array = [{'id': 1, 'name': 'xxx'},
{'id': 2, 'name': 'yyy'},
{'id': 3, 'name': 'zzz'}];
var searchValue --> id==1
should be something like this?
function search_array(array,valuetofind) {
if array.indexof({'id': valuetofind}) != -1 {
return array[array.indexof({'id': valuetofind})]
} else {
return {'id': -1}
}
}

This returns the object if a match exists and -1 if there's no match.
function search_array(array,valuetofind) {
for (i = 0; i < array.length; i++) {
if (array[i]['id'] === valuetofind) {
return array[i];
}
}
return -1;
}

If you simply need to make sure the id exists try this:
function search_array(array, valuetofind) {
var exists = false;
for(i=0;i<array.length;i++) {
if(array[i].id == valuetofind) {
exists = true;
}
}
return exists;
}
My method may be a little long winded cycling through each part but i checked and it works
search_array(array, 4) [False]
search_array(array, 1) [True]

try this
search(nameKey, myArray){
for (var i=0; i < myArray.length; i++) {
if (myArray[i].name === nameKey) {
return myArray[i];
}
}
}
var array = [
{ name:"string 1", value:"this", other: "that" },
{ name:"string 2", value:"this", other: "that" }
];
var resultObject = search("string 1", array);

Related

How to check if array is unique on specific object property?

I have an array of objects:
var array1 = [
{
property1: 10,
property2: "abc"
},
{
property1: 11,
property2: "def"
},
{
property1: 10,
property2: "ghi"
}
];
Now what I want is this array will be said not unique as per value of property1.
This means that this array contains 2 elements with property1=10, so the array does not contain unique value of property1.
To check this, I can use a for loop:
for (var i = 0; i < array1.length; i++) {
var array2 = array1.slice(); // copy array
array2.remove(array1[i]);
var temppropety1 = array1[i].property1;
for (var j = 0; j < array2.length; j++) {
if (array2[J].property1==temppropety1) {
return true;
}
}
}
But is there an easier way or a library to find this?
Here is a straightforward way to test for uniqueness on property1. Loop through the objects in the outer array and add each object's property1 to a temp array if it is not already in that temp array. If a duplicate value is encountered, return false meaning property1 is not unique.
function isUnique(arr) {
var tmpArr = [];
for(var obj in arr) {
if(tmpArr.indexOf(arr[obj].property1) < 0){
tmpArr.push(arr[obj].property1);
} else {
return false; // Duplicate value for property1 found
}
}
return true; // No duplicate values found for property1
}
Demo: http://jsbin.com/lohiqihipe/1/
First, you could reduce (aggregate) the objects by grouping them by the value of property1:
var grouped = array.reduce(function(grouped, item) {
var propertyValue = item.property1;
grouped[propertyValue] = (grouped[propertyValue] || 0) + 1;
return grouped;
}, {});
Then you check that every key of the resulting object has a value of 1:
var result = Object.keys(grouped).every(function(key) {
return grouped[key] === 1;
});
I suggest that array can be quite big so I'd prefer not to copy it and just validate properties.
Also it is not an option to use map function of array because in this case you won't be able to break a cycle on first match:
var equals = function(array) {
var co = {};
var unique = true;
for(var i = 0; i < array.length; i++) {
var o = array[i];
if (co[o.property1]) {
unique = false;
break;
} else {
co[o.property1] = true;
}
}
return unique;
};
You can convert your array to flat structure:
array1.map(function(item) { return item.property1; });
and now your problem simplify to check duplicates in simple array
var array1 = ["a","b","b","c","d","e","f"];
var uniqueItems = [];
$.each(array1, function(i, el){
if($.inArray(el, uniqueItems) === -1) uniqueItems.push(el);
});
References:
https://stackoverflow.com/a/840808/4772988
https://stackoverflow.com/a/9229932/4772988
You can use a couple of helpers to abstract it:
var uniqBy = function(f, xs) {
var seen = []
return xs.filter(function(x) {
var fx = f(x)
if (seen.indexOf(fx) > -1) return
seen.push(fx)
return true
})
}
var dot = function(k) {
return function(obj) {
return obj[k]
}
}
Then filter out duplicates by the property, and compare the length of the result to the original array. If they don't match, then they must not be unique:
var res = uniqBy(dot('property1'), array1)
var isUnique = array1.length === res.length
console.log(isUnique) // false
If you got only numbers or only strings to remove duplicates from, then you can improve performance by using an object instead of an array to keep track of elements seen so far.
You can use lodash library to achieve this.
Here is the library documentation: https://lodash.com/docs/4.17.5#filter
Method:-
function isDuplicatesPresent(list, propertyName){
return _.filter(list, function (value) {
return _.filter(list, function(innerValue){ reutrn innerValue[propertyName] === value[propertyName]}).length > 1;
}).length > 0;
}
Example:-
var users = [
{ user: 'barney', age: 36, active: true },
{ user: 'fred', age: 40, active: false },
{ user: 'barney', age: 37, active: true}
];
let duplicates = _.filter(users, function (value) {
return _.filter(users, {user:value.user}).length > 1;
});
Result:
console.log(duplicates)
> [
{"user": "barney","age": 36,"active": true},
{"user": "barney","age": 37,"active": true}
];

Select item of array of objects from deep property

Say I have this array:
var myArray = [
{
"name": "item 1",
"id": 123
},{
"name": "item 2",
"id": 456
}
];
What would be the proper way to get an item based on the id property? With this example, say I know I want the item for which item.id == 456.
I don't want jquery answers.
Try this:
var item = myArray.filter(function(item) { return item.id === 456; })[0];
You can implement a search function like below:
function searchArray(id) {
for(var i = 0; i < myArray.length; i++) {
if(myArray[i].id == id) {
return myArray[i];
}
}
console.log(id + ' not found');
}
for ( var index = 0; index < myArray.length; index++ ) {
if ( myArray[index].id == 456 )
//Item found
}
try
for (var i in myArray) {
if(myArray[i].id == 456) {
return myArray[i];
}
}

Getting index of array object element given multiple object keys

I know given a single key (for example, if I know the object.name = 'Sam') using:
var index = array.map(function(el) {return el.name}).indexOf('Sam');
I can get the index of the array element with object.name = 'Sam'
However say I have several elements with object.name ='Sam' in the array, but now I know know the object.name, object.age and object.size - is it possible to adapt the above code to get the index but also checking against object.age and object.size?
Assuming you have the values in variables such as name, age and size as you mentioned in comments, You can use a function like:
function findInArray(arr) {
for (var i = 0; i < arr.length; i++) {
var el = arr[i];
if (el.name == name && el.age == age && el.size == size)
return i;
}
return -1;
};
Which will return the index of object in array if match is found, and -1 otherwise...
var data = [{
name: "Sis",
age: "17",
size: "10"
}, {
name: "Sam",
age: "17",
size: "10"
}, {
name: "Som",
age: "17",
size: "10"
}],
name = "Sam",
age = "17",
size = "10";
function findInArray(arr) {
for (var i = 0; i < arr.length; i++) {
var el = arr[i];
if (el.name == name && el.age == age && el.size == size)
return i;
}
return -1;
};
console.log(findInArray(data));
If you're using the awesome underscore library there's a _.findWhere function.
var sam21 = _.findWhere(people, {
name: 'Sam',
age: 21
});
if you want something without a whole other library you can use .filter.
var sam21 = people.filter(function(person) {
return person.age === 21 && person.name === 'Sam';
});
I just noticed you're looking for the index. This answer can be useful: https://stackoverflow.com/a/12356923/191226
You could use a function like this one
indexOfObjectArray = function(array, keyvalues) {
for (var i = 0; i < array.length; i++) {
var trueCount = 0;
for (var j = 0; j < keyvalues.length; j++) {
if (array[i][keyvalues[j]['key']] == keyvalues[j]['value']) {
trueCount++;
}
}
if (trueCount === keyvalues.length) return i;
}
return -1; }
and use it like that for example:
var yourArray = [{id: 10, group: 20},...];
var keyvalues = [
{ 'key': 'id', 'value': 10 },
{ 'key': 'group', 'value': 20 }];
var index = indexOfObjectArray(yourArray, keyvalues );
This function will return the index of an object that has id = 10 and group = 20

Remove JSON entry by value [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Delete from array in javascript
I have the following JSON object:
[id:84,id:92,id:123,id:2353]
How would I go about removing the item which the value is "123" using javascript?
or if I formatted the json as
[84, 92, 123, 2353]
How would it be removed in this case?
Assume you have this:
var items = [{ id: 84 }, { id: 92 }, { id: 123 }, { id: 2353 }];
var filtered = items.filter(function(item) {
return item.id !== 123;
});
//filtered => [{ id: 84 }, { id: 92 }, { id: 2353 }]
Supposing you actually have an object from a json in the json variable
for (key in json) {
if (json.hasOwnProperty(key) && json[key] == 123) {
delete json[key];
}
}
Shorter alternative would be:
var newArr = [{id:84}, {id:92}, {id:123}, {id:2353}].filter(function(a) {
return a.id != 123;
});
If you have this:
var arr = [{id:84}, {id:92}, {id:123}, {id:2353}]
To remove the item with value 123, you can do:
for(var i = 0; i < arr.length; i++) {
if(arr[i].id == 123) {
arr.splice(i, 1);
break;
}
}
function removeClass(obj, cls) {
var classes = obj.className.split(' ');
for(i=0; i<classes.length; i++) {
if (classes[i] == cls) {
classes.splice(i, 1);
i--; // (*)
}
}
obj.className = classes.join(' ');
}
var obj = { className: 'open menu menu' }
removeClass(obj, 'menu')
alert(obj.className)
You can use splice function, like this:
var data = [{id:84}, {id:92}, {id:123}, {id:2353}];
function remove(){
for(var i = 0, max = data.length; i < max; i++) {
var a = data[i];
if(a.id === 123) {
data.splice(i, 1);
break;
}
}
}
remove();
Seems like you want to avoid a loop. Assuming it's available, you can use .filter:
[{id:84},{id:92},{id:123},{id:2353}]
.filter(function (elem) { return elem.id !== 123; });
This technically does do a loop, but at least you don't have to look at it.
Assuming your "json" is really an array, like [84, 92, 123, 2353]:
var myString = "[84, 92, 123, 2353]";
var myArray = JSON.parse(myString);
var index = myArray.indexOf(123); // whatever value you are looking for
myArray.splice(index, 1);
http://jsfiddle.net/7vkK6/
Assuming I'm understanding your question and comments correctly you can do something like this:
var old_array = [{id: 84},...];
var new_array = [];
for(var i = 0, len = old_array.length; i++) {
if (old_array[i].id != 123) new_array.push(old_array[i]);
}
What you have currently is not JSON so I'll give you some different options.
If you have an Array arr = [84,92,123,2353] then
arr = arr.filter(function (x) {return x !== 123;}); // all occurrences
// OR
arr.splice(arr.indexOf(123), 1); // first occurrence only
If you have an Object obj = {"84": a, "92": b, "123": c, "2353": d}, a to d some expressions, then
delete obj['123']; // obj now {"84": a, "92": b, "2353": d}
1) JSON is a string, not an array or an object.
var json = "[1,2,3]";
2) Valid JSON NEEDS to be valid JS
var myJSObj = { 1,2,3 }, // broken
myJSArr = [ name : 1, name2 : 2 ]; // broken
3) If you have a JS Array, you can remove an element by using [].splice
var arr = [ 1, 2, 3, 4 ],
i = 0, l = arr.length,
test = 4;
for (; i < l; i += 1) {
if (arr[i] === test) { arr.splice(i, 1); } // remove 1 starting at i
}
4) If you have an object with named keys, you can use delete
var obj = { val : 1 };
delete obj.val;

json index of property value

I need to get the index of the json object in an array whose by the objects id
here is the example code
var list = [ { _id: '4dd822c5e8a6c42aa70000ad',
metadata:
{ album: 'American IV: Man Comes Around',
song: 'Hurt',
coverart: 'http://images.mndigital.com/albums/044/585/435/m.jpeg',
artist: 'Johnny Cash',
length: 216,
mnid: '44585439' } },
{ _id: '4dd80b16e8a6c428a900007d',
metadata:
{ album: 'OK Computer (Collector\'s Edition)',
song: 'Paranoid Android',
coverart: 'http://images.mndigital.com/albums/026/832/735/m.jpeg',
artist: 'Radiohead',
length: 383,
mnid: '26832739' } },
{ _id: '4dd68694e8a6c42c80000479',
metadata:
{ album: 'The Presidents Of The United States Of America: Ten Year Super Bonus Special Anniversary Edition',
song: 'Lump',
coverart: 'http://images.mndigital.com/albums/011/698/433/m.jpeg',
artist: 'The Presidents Of The United States Of America',
length: 134,
mnid: '11698479' } }
]
then pseudo code
var index_of = list.indexOf("4dd80b16e8a6c428a900007d");
obviously that is not gonna work but I wonder if there is anyway to do this without looping to find the index ?
var i = list.length;
while( i-- ) {
if( list[i]._id === '4dd80b16e8a6c428a900007d' ) break;
}
alert(i); // will be -1 if no match was found
You can try Array.prototype.map, based on your example it will be:
var index = list.map(function(e) { return e._id; }).indexOf('4dd822c5e8a6c42aa70000ad');
Array.prototype.map is not available on IE7 or IE8. ES5 Compatibility
Since there is no index of your data structure by _id, something is going to have to loop over the structure and find an _id value that matches.
function findId(data, id) {
for (var i = 0; i < data.length; i++) {
if (data[i]._id == id) {
return(data[i]);
}
}
}
Just loop through the list until you find the matching id.
function indexOf(list, id) {
for (var i = 0; i < list.length; i++) {
if (list[i]._id === id) { return i; }
}
return -1;
}
function index_of(haystack, needle) {
for (var i = 0, l = haystack.length; i < l; ++i) {
if( haystack[i]._id === needle ) {
return i;
}
}
return -1;
}
console.log(index_of(list, '4dd80b16e8a6c428a900007d'));
same as the above, but caches the length of the haystack.
a prototypical way
(function(){
if (!Array.prototype.indexOfPropertyValue){
Array.prototype.indexOfPropertyValue = function(prop,value){
for (var index = 0; index < this.length; index++){
if (prop in this[index]){
if (this[index][prop] == value){
return index;
}
}
}
return -1;
}
}
})();
// usage:
list.indexOfPropertyValue('_id','4dd80b16e8a6c428a900007d'); // returns 1 (index of array);
list.indexOfPropertyValue('_id','Invalid id') // returns -1 (no result);
var indexOfArray = list.indexOfPropertyValue('_id','4dd80b16e8a6c428a900007d');
list[indexOfArray] // returns desired object.

Categories

Resources