Get an object of a dictionary by attribute - javascript

I have a dictionary:
[ object , object, object, object, object ]
object contains: id and name.
I have an Id ('123456') and I want to get the object with this id.
Is there another solution how can I do it without for loop on the objects?
any help appreciated!

Hate loops, then go for recursion, i just assumed that you are having that array in a variable called as xArr
var xObj = check(0,"123456");
function check(cnt,id) {
if(xArr[cnt].id === id)
{
return xArr[cnt];
}
else if(cnt === xArr.length - 1) {
return null;
}
else {
cnt += 1;
return check(cnt, id);
}
}

That's an array, you could use jQuery.grep to get the elements with id "123456".
var result = $.grep(arr, function(obj) {
return obj.id === '123456';
});
Array also provide an .filter method (need a polyfill for browsers not support it):
var result = arr.filter(function(obj) {
return obj.id === '123456';
});

If you want to use a vanilla JS method, you can use filter. This pretty much does the same as $.grep.
var result = arr.filter(function (obj) {
return obj.id === '123456';
});

Related

Why doesn't indexOf work after pushing object in array

Im trying to get indexOf of a object after its pushed inside a array.
This is not returning the same value back as i do indexOf whenever objext is allready in the array.
SCENARIO
var arr = [];
setInterval(function() {
var path = { one: "f00"};
if (typeof path !== "undefined") {
if (arr.indexOf(path) === -1) {
console.log("Not Exists!!")
arr.push(path)
} else {
console.log("Exists!!")
}
}
console.log(arr)
}, 2000)
What is the different between the working of
The issue is that JavaScript doesn't do a deep compare of objects, so it doesn't recognize them as the same.
var a = { name: 'foo' }
var b = { name: 'foo' }
a === b // false
However, since you have access to the object before the insert, you can save a reference to it, and then search for that reference:
var arr = []
var obj = { path: 'foo' }
arr.push(obj)
arr.indexOf(obj) // 0
This is because indexOf uses the strict equality === comparison. So in this case, the references to obj and the object at arr[0] are the same.
Edit
Based on your changed question, here is a way to write your function to do what you want:
var arr = [];
function findAdnSet(obj) {
var index = arr.indexOf(obj);
if (index !== -1) {
return index;
} else {
arr.push(obj);
return arr.length - 1; // No reason to use indexOf here, you know the location since you pushed it, meaning it HAS to be the last element in the array
}
}
var path = { name: 'foo' };
findAndSet(path);
A more robust option than using indexOf since your function might not always have a good reference available is to use find/findIndex:
var arr = [];
function findAndSet(obj) {
var index = arr.findIndex(function(item) {
if (item.name === 'foo') {
return true;
}
});
if (index) { // findIndex returns `undefined` if nothing is found, not -1
return index;
} else {
arr.push(obj);
return arr.length - 1;
}
}
// You don't need a reference anymore since our method is doing a "deep" compare of the objects
findAndSet({ name: 'foo' });
The first time you do indexOf you push and search for the object 'path' so it is found. The second time you create an object and add push it to the array, and then search for another new object (which happens to have the same values), but since it is not the same object that you pushed it is not found.

Javascript / Jquery - .every() equivalent for operating on object

How can test over an object like the array.every() method? Trying to detect if all the terms in a query object are blank before sending it on. Obviously I could just write a little routine in a for loop, but I'm expecting there's a more succinct way of accomplishing this.
// array - works
var queryArr = [ "", "" ];
if(!queryArr.every(function(el, i, arr) { return el == "" } )) {
alert("nothing to search");
}
// object - "undefined is not a function"
var queryObj = { term1: "", term2: "" };
if(!queryObj.every(function(el, i, arr) { return el == "" } )) {
alert("nothing to search");
}
Map can be used call a function on each object in an array.
http://api.jquery.com/jquery.map/
You could implement your own every method this way:
Object.prototype.every=function(evalFunction){
var self=this,
property;
if(typeof evalFunction!=='function')
return evalFunction;
for(property in self){
if(self.hasOwnProperty(property) && !evalFunction(self[property], property, self)){
return false;
}
}
return true;
}
Then you could use the new every method on objects the same way you do with arrays But if you only want to test this once on your code I sugest to use for in loop or robisrob's map solution

jQuery - how to find a specific JavaScript object inside an array within an object?

I have an object in javaScript:
var stuffObject = {
stuffArray1 : [object1, object2, object3],
stuffArray2 : [object4, object5, object6]
}
object1 to 6 look like this:
object1 = {
dataStuff : {
stuffId: "foobar"
}
}
My question: given the key "foobar", how do I retrieve object1 from the stuffObject using jQuery? The key "stuffId" always has a unique value.
You won't get around iterating over the set to find the object you are looking for. jQuery can't really help with that. Its purpose is DOM manipulation. If you want functionality to deal with objects, sets, lists, etc., check out lodash.
I wrote a function to deal with the problem. I hope it's understandable.
var stuffObject = {
stuffArray1 : [{dataStuff: {stuffId: 'foobar'}}, {dataStuff: {stuffId: 'foo'}}, {}],
stuffArray2 : [{}, {dataStuff: {stuffId: 'bar'}}, {}]
}
function getObjByStuffId(stuffObject, stuffId) {
var key, arr, i, obj;
// Iterate over all the arrays in the object
for(key in stuffObject) {
if(stuffObject.hasOwnProperty(key)) {
arr = stuffObject[key];
// Iterate over all the values in the array
for(i = 0; i < arr.length; i++) {
obj = arr[i];
// And if it has the value we are looking for
if(typeof obj.dataStuff === 'object'
&& obj.dataStuff.stuffId === stuffId) {
// Stop searching and return the object.
return obj;
}
}
}
}
}
console.log('foobar?', getObjByStuffId(stuffObject, 'foobar') );
console.log('foo?', getObjByStuffId(stuffObject, 'foo') );
console.log('bar?', getObjByStuffId(stuffObject, 'bar') );
Thanks for the help guys, using the input of other people I have solved it myself:
getStuffById: function(id){
for (stuffArray in stuffObject) {
for (stuff in stuffObject[stuffArray]) {
if (stuffObject[stuffArray][stuff].dataStuff.stuffId == id) {
return stuffObject[stuffArray][stuff];
}
}
}
return null;
}
This also works better than the (now deleted) answer that uses .grep(), as this function terminates as soon as it finds the correct object.

Check if value exists in JavaScript object

How would I check in my array of objects, if a specific item exists (in my case MachineId with id 2)?
[{"MachineID":"1","SiteID":"20"},{"MachineID":"2","SiteID":"20"},{"MachineID":"3","SiteID":"20"},{"MachineID":"4","SiteID":"20"}]
I tried this:
if (index instanceof machineIds.MachineID) {
alert('value is Array!');
} else {
alert('Not an array');
}
In cross browser way you may use jQuery.grep() method for it:
var item = $.grep(machineIds, function(item) {
return item.MachineID == index;
});
if (item.length) {
alert("value is Array!");
}
The simplest to understand solution is to loop over the array, and check each one.
var match;
for (var i = 0; i < yourArray.length; i++) {
if (yourArray[i].MachineId == 2)
match = yourArray[i];
}
Note if there is more than one matching item, this will return the last one. You can also dress this up in a function.
function findByMachineId(ary, value) {
var match;
for (var i = 0; i < ary.length; i++) {
if (ary[i].MachineId == value)
match = ary[i];
}
return match;
}
There are many standard solution, you don't need third party libraries or loop iteratively.
Array some method - since JavaScript 1.6.
Array find method - since ES6
Array findIndex method - since ES6
For example, using some();
var yourArray = [{"MachineID":"1","SiteID":"20"},{"MachineID":"2","SiteID":"20"},{"MachineID":"3","SiteID":"20"},{"MachineID":"4","SiteID":"20"}];
var params = {searchedID: "2", elementFound: null};
var isCorrectMachineID = function(element) {
if (element.MachineID == this.searchedID);
return (this.elementFound = element);
return false;
};
var isFound = yourArray.some(isCorrectMachineID, params)
Array some method accepts two parameters:
callback - Function to test for each element.
thisObject - Object to use as this when executing callback.
Callback function is not coupled with the iteration code and, using thisObject parameter, you can even return to the caller the element found or more data.
If such an element is found, some immediately returns true
http://jsfiddle.net/gu8Wq/1/
You could use this condition:
if (arr.filter(function(v){return this.MachineID == 2;}).length > 0)
Old question at this point, but here's an ES6 solution that uses Array.find:
let machine2 = machines.find((machine) => machine.id === '2');
if (machine2) {
// ...
}
var item = [{"MachineID":"1","SiteID":"20"},{"MachineID":"2","SiteID":"20"},{"MachineID":"3","SiteID":"20"},{"MachineID":"4","SiteID":"20"}];
var newItem = item.filter(function(i) {
return i.MachineID == 2; //it will return an object where MachineID matches with 2
});
console.log(newItem); // will print [{"MachineID":"2","SiteID":"20"}]

jQuery: Index of element in array where predicate

I have an array of objects. Each object has, among others, an ID attribute. I want to find the index in the array of the object with a specific ID. Is there any elegant and simple way to do this in jQuery?
See [`Array.filter`][1] to filter an array with a callback function. Each object in the array will be passed to the callback function one by one. The callback function must return `true` if the value is to be included, or false if not.
var matchingIDs = objects.filter(function(o) {
return o.ID == searchTerm;
});
All objects having the ID as searchTerm will be returned as an array to matchingIDs. Get the matching element from the first index (assuming ID is unique and there's only gonna be one)
matchingIDs[0];
[1]: https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter
Update:
Checkout findIndex from ECMAScript 6.
items.findIndex(function(item) { item.property == valueToSearch; });
Since findIndex isn't available on most browsers yet, you could backfill it using this implementation:
if (!Array.prototype.findIndex) {
Array.prototype.findIndex = function(predicate) {
if (this == null) {
throw new TypeError('Array.prototype.findIndex called on null or undefined');
}
if (typeof predicate !== 'function') {
throw new TypeError('predicate must be a function');
}
var list = Object(this);
var length = list.length >>> 0;
var thisArg = arguments[1];
var value;
for (var i = 0; i < length; i++) {
value = list[i];
if (predicate.call(thisArg, value, i, list)) {
return i;
}
}
return -1;
};
}
In the case you should use for loop in javascript instead of using jQuery. See way 3 in http://net.tutsplus.com/tutorials/javascript-ajax/10-ways-to-instantly-increase-your-jquery-performance/
UPDATED: jQuery is written in javascript and it can not be faster than another code written also in javascript. jQuery is very good if you work with the DOM, but doesn't really help if you're working with simple javascript arrays or objects.
The code you're looking for can be something like this:
for (var i=0, l = ar.length; i<l; i++) {
if (ar[i].ID === specificID) {
// i is the index. You can use it here directly or make a break
// and use i after the loop (variables in javascript declared
// in a block can be used anywhere in the same function)
break;
}
}
if (i<l) {
// i is the index
}
Important that you should hold some simple javascript rules: Always declare local variables (don't forget var before variable declaration) and cache any properties or indexes that you use more than one time in a local variable (like ar.length above). (See for example http://wiki.forum.nokia.com/index.php/JavaScript_Performance_Best_Practices)
Not really elegant, but a cute trick:
var index = parseInt(
$.map(array, function(i, o) { return o.id === target ? i : ''; }).join('')
);
jQuery doesn't have a lot of functional constructs like that; the philosophy of the library is really focused on the job of DOM wrangling. They won't even add a .reduce() function because nobody can think of a reason it'd be useful to the core functionality.
The Underscore.js library has a lot of such facilities, and it "plays nice" with jQuery.
There are no built-in methods for this; the [].indexOf() method doesn't take a predicate, so you need something custom:
function indexOf(array, predicate)
{
for (var i = 0, n = array.length; i != n; ++i) {
if (predicate(array[i])) {
return i;
}
}
return -1;
}
var index = indexOf(arr, function(item) {
return item.ID == 'foo';
});
The function returns -1 if the predicate never yields a truthy value.
Update
There's Array.findIndex() that you could use now:
const arr = [{ID: 'bar'}, {ID: 'baz'}, {ID: 'foo'}];
const index = arr.findIndex(item => item.ID === 'foo');
console.log(index); // 2
Use jOrder. http://github.com/danstocker/jorder
Feed your array into a jOrder table, and add an index on the 'ID' field.
var table = jOrder(data)
.index('id', ['ID']);
Then, get the array index of an element by:
var arrayidx = table.index('id').lookup([{ ID: MyID }]);
If you want the entire row, then:
var filtered = table.where([{ ID: MyID }]);
Voila.

Categories