MyIds has just two Id numbers 1 and 2
var MyIds = [1,2]
but MyObject has three Id numbers 1, 2 and 3 (In reality this has about 500 Id's)
var MyObject = [{id:1,size:21,length:31},{id:2,size:22,length:32},{id:3,size:23,length:33}]
and I want to make a new variable that looks like this, I need some magic code that will compare the two variables and only return the details of the objects where the Is's match
var Result = [{id:1,size:21,length:31},{id:2,size:22,length:32}]
I'm happy to use jQuery if it help
Use Array.prototype.filter()
var Result = MyObject.filter(function(item){
return MyIds.indexOf(item.id) >-1;
});
It can be easily solved with underscore or lodash with something like:
Result = _.filter(MyObject, function (item) {
return _.indexOf(item.id, MyIds) !== -1;
});
I admit, this is a lazy answer. There is probably a way to make it without adding a news library. But lodash is so cool :)
It can be done without jQuery:
var MyIds = [1,2];
var MyObject = [{id:1,size:21,length:31},{id:2,size:22,length:32},{id:3,size:23,length:33}];
var Result = [];
MyObject.forEach(function(element) {
MyIds.forEach(function(id){
if(element.id == id)
Result.push(element);
});
});
A more diverse sollution without using any library:
function find(propName, filters, collection){
var temp = [];
for(var i = 0; i < collection.length; i++){
for(var j = 0; j < filters.length; j++){
if(collection[i][propName] === filters[j]){
temp.push(collection[i]);
break;
}
}
}
return temp;
Related
Ok, this might be easy for some genius out there but I'm struggling...
This is for a project I'm working on with a slider, I want an array the slider can use for snap points/increments... I'm probably going about this in a mental way but its all good practice! Please help.
var frootVals = [1,2,3,4,5];
var frootInc = [];
for (i=0; i<=frootVals.length; i++) {
if (i == 0){
frootInc.push(frootVals[i]);
}
else{
frootInc.push(frootInc[i-1] += frootVals[i])
}
};
What I'm trying to do is create the new array so that its values are totals of the array elements in frootVals.
The result I'm looking for would be this:
fruitInc = [1,3,6,10,15]
For a different take, I like the functional approach:
var frootVals = [1,2,3,4,5];
var frootInc = [];
var acc = 0;
frootVals.forEach(function(i) {
acc = acc + i;
frootInc.push(acc);
});
var frootVals = [1,2,3,4,5]
, frootInc = [];
// while i < length, <= will give us NaN for last iteration
for ( i = 0; i < frootVals.length; i++) {
if (i == 0) {
frootInc.push(frootVals[i]);
} else {
// rather than frootIne[ i-1 ] += ,
// we will just add both integers and push the value
frootInc.push( frootInc[ i-1 ] + frootVals[ i ] )
}
};
There were a few things wrong with your code check out the commenting in my code example. Hope it helps,
This will do:
var frootVals = [1,2,3,4,5];
var frootInc = [];
for (i=0; i < frootVals.length; i++) { // inferior to the length of the array to avoid iterating 6 times
if (i == 0) {
frootInc.push(frootVals[i]);
}
else {
frootInc.push(frootInc[i-1] + frootVals[i]) // we add the value, we don't reassign values
}
};
alert(JSON.stringify(frootInc));
jsfiddle here: http://jsfiddle.net/f01yceo4/
change your code to:
var frootVals = [1,2,3,4,5];
var frootInc = [frootvals[0]]; //array with first item of 'frootVals' array
for (i=1; i<frootVals.length; i++) {
frootInc.push(frootInc[i-1] + frootVals[i]); //remove '='
}
Here's a very simple pure functional approach (no vars, side-effects, or closures needed):
[1,2,3,4,5].map(function(a){return this[0]+=a;}, [0]);
// == [1, 3, 6, 10, 15]
if you name and un-sandwich the function, you can use it over and over again, unlike a hard-coded var name, property name, or for-loop...
Apologies if this is a duplicate, but I can't seem to find the solution.
I am trying to find a specific string pattern in an array.
I want to find all values in data that contain 'underscore r underscore'. I then want to create a new array that contains only those keys and values.
var data = ["something", "bar_r_something"];
var resultArray = new Array();
for (var i = 0; i < data.length; i++) {
var bar = /_r_/;
if ($.inArray(bar, data[i].length) > 0)
{
console.log("found _r_");
resultArray.push(data[i]);
}
};
I just can't seem to get that $.inArray to work, it seems to always kick out -1.
var data = ["something", "bar_r_something"];
var resultArray = new Array();
for (var i = 0; i < data.length; i++) {
var bar = /_r_/;
if (bar.test(data[i])) {
alert("found _r_");
resultArray.push(data[i]);
}
};
console.log(resultArray);
Here you go, it doesn't use $.inArray, but Regex instead, hope that's cool!
EDIT
If you wanted to go a bit more fancy, you can use JavaScript's filter method like so:
var data = ["something", "bar_r_something"];
var resultArray = data.filter(function(d){
return /_r_/.test(d);
});
console.log(resultArray);
I think what you are looking for is $.grep(). Also $.inArray() does not test the values against a regex, it tests for equality.
var regex = /_r_/
var resultArray = $.grep(data, function(item){
return regex.test(item)
})
Demo: Fiddle
I have a lot of objects that I'm trying to filter out duplicates from. When an object has a property, IMAGEURL which is present in another object, I want to ignore this object and move on.
I'm using nodeJS for this so if there's a library I can use to make it easier let me know.
I've done similar implementations before with checking string values in arrays, doing something like:
var arr = ['foo', 'bar'];
if(arr.indexOf('foo') == -1){
arr.push('foo')
}
But this won't work for objects, as best I can tell. What are my options here? To put it more simply:
var obj1 = {IMAGEURL: 'http://whatever.com/1'};
var obj2 = {IMAGEURL: 'http://whatever.com/2'};
var obj3 = {IMAGEURL: 'http://whatever.com/1'};
var arr = [obj1, obj2, obj3];
var uniqueArr = [];
for (var i = 0; i<arr.length; i++){
// For all the iterations of 'uniqueArr', if uniqueArr[interation].IMAGEURL == arr[i].IMAGEURL, don't add arr[i] to uniqueArr
}
How can I do this?
You can just use an inner loop (keeping track of whether we've seen the loop by using a seen variable -- you can actually use labels here, but I find the variable method to be easier to read):
for (var i = 0; i<arr.length; i++){
var seen = false;
for(var j = 0; j != uniqueArr.length; ++j) {
if(uniqueArr[j].IMAGEURL == arr[i].IMAGEURL) seen = true;
}
if(!seen) uniqueArr.push(arr[i]);
}
Here is a concise way:
var uniqueArr = arr.filter(function(obj){
if(obj.IMAGEURL in this) return false;
return this[obj.IMAGEURL] = true;
}, {});
http://jsfiddle.net/rneTR/2
Note: this is concise, but orders of magnitude slower than Nirk's answer.
See also: http://monkeyandcrow.com/blog/why_javascripts_filter_is_slow/
The title may a little confusing. But i think it is clear:
var a = ["A1", "B13", "C123"];
I want to ignore first value in elements and get rest of them. So my new array should look like this:
var b = ["1", "13", "123"];
Use .map() to create a new Array of modified values of the original.
var b = a.map(function(item) {
return item.slice(1);
});
This iterates the original Array, passes each item in the Array as the first argument to the function, and sets the return value of the function as the values for the new Array.
For IE8 and lower, you'll need to implement a patch. One is available from MDN.
Using .map, you can return a new array which is generated by passing every element in the existing array through a function:
var b = a.map(function(v) {
return v.substr(1);
});
Note that .map is an ES5 function that doesn't exist on older browsers. A shim is available at the above link.
var b = [];
for (var i = 0; i < a.length; ++i)
{
b[i] = a[i].substring(1);
}
Live Demo
The forEach way
var a = ["A1", "B13", "C123"],
b = [];
a.forEach(function (element) {
b.push(element.slice(1));
});
console.log(b);
on jsfiddle
The map way
var b = a.map(function (element) {
return element.slice(1);
});
The for way
var l = a.length;
var b = [];
for (var i = 0; i < l; i += 1) {
b.push(a[i].slice(1));
}
Ultimate speed is still the for loop (except for maybe grand daddy)
So as I ended up including all of the above, it didn't feel right to leave the grand daddy of them all out of the equation.
The while way
var b = [];
var i = 0;
var l = a.length;
while (i < l) {
b.push(a[i].slice(1));
i += 1;
}
I also include a RegExp and jquery version for a bit of a giggle.
(lodash also has it's own map function)
You can see the jsperf
I have two JavaScript arrays below that both have the same number of entries, but that number can vary.
[{"branchids":"5006"},{"branchids":"5007"},{"branchids":"5009"}]
[{"branchnames":"GrooveToyota"},{"branchnames":"GrooveSubaru"},{"branchnames":"GrooveFord"}]
I want to combine these two arrays so that I get
[{"5006":"GrooveToyota"},{"5007":"GrooveSubaru"},{"5008":"GrooveFord"}]
I'm not sure how to put it into words but hopefully someone understands. I would like to do this with two arrays of arbitrary length (both the same length though).
Any tips appreciated.
It's kind of a zip:
function zip(a, b) {
var len = Math.min(a.length, b.length),
zipped = [],
i, obj;
for (i = 0; i < len; i++) {
obj= {};
obj[a[i].branchids] = b[i].branchnames;
zipped.push(obj);
}
return zipped;
}
Example (uses console.log ie users)
var ids = [{"branchids":"5006"},{"branchids":"5007"},{"branchids":"5009"}];
var names = [{"branchnames":"GrooveToyota"},{"branchnames":"GrooveSubaru"},{"branchnames":"GrooveFord"}];
var combined = [];
for (var i = 0; i < ids.length; i++) {
var combinedObject = {};
combinedObject[ids[i].branchids] = names[i].branchnames;
combined.push(combinedObject);
}
combined; // [{"5006":"GrooveToyota"},{"5006":"GrooveSubaru"},{"5006":"GrooveFord"}]
Personally, I would do it IAbstractDownvoteFactor's way (+1), but for another option, I present the following for your coding pleasure:
var a = [{"branchids":"5006"},{"branchids":"5007"},{"branchids":"5009"}];
var b = [{"branchnames":"GrooveToyota"},{"branchnames":"GrooveSubaru"},{"branchnames":"GrooveFord"}];
var zipped = a.map(function(o,i){ var n={};n[o.branchids]=b[i].branchnames;return n;});
similar to #robert solution but using Array.prototype.map
var ids = [{"branchids":"5006"},{"branchids":"5007"},{"branchids":"5009"}],
names = [{"branchnames":"GrooveToyota"},{"branchnames":"GrooveSubaru"},{"branchnames":"GrooveFord"}],
merged = ids.map(function (o, i) { var obj = {}; obj[o.branchids]=names[i].branchnames; return obj; });
merged; //[{5006: "GrooveToyota"}, {5006: "GrooveSubaru"}, {5006:"GrooveFord"}]
Cheers!