I need to check if at least one element in an array pass a condition.
The condition depends on a variable.
For example, I'm using something like this:
function condition(previousValue, index, array) {
return additonalValue.indexOf(previousValue) + previousValue.indexOf(additonalValue) < -1;
}
I can't figure out how can I pass the "additonalValue" parameter to the array.some(condition) expression.
I'm using jQuery so, an alternative for it is welcome.
Is there a way to pass a parameter to array.some() method?
If you want to pass an additional parameter to the function that is placed inside the some method you can use bind.
var myArray = ['a', 'b', 'c', 'd'];
var otherValue = 'e';
function someFunction(externalParameter, element, index, array) {
console.log(externalParameter, element, index, array);
return (element == externalParameter);
}
myArray.some(someFunction.bind(null, otherValue));
This would give you:
e a 0 ["a", "b", "c", "d"]
e b 1 ["a", "b", "c", "d"]
e c 2 ["a", "b", "c", "d"]
e d 3 ["a", "b", "c", "d"]
false
Using a closure looks like the simplest solution :
var additonalValue = 79;
var r = myArray.some(function(previousValue) {
return additonalValue.indexOf(previousValue) + previousValue.indexOf(additonalValue) < -1;
});
The some() function accepts additional arguments in the form of an array, that is set to this inside the callback, so you could pass a number of values that way :
var arr = ['one', 'two', 'three'];
var val = 'two';
var r = arr.some(function(value) {
return this[0] == value;
}, [val]);
FIDDLE
Related
I have an array like this -
["a", "a", "b", "c", "d", "e"]
I want to operate on this and filter it to remove only the first occurence of every element in the array.
The output in the above case is expected to be - ["a"]
How can I achieve this using JavaScript or Lodash?
By wanting the first one of duplicate following items, you could use Array#lastIndexOf along with a check of the actual index.
const
data = ["a", "a", "b", "c", "d", "e"],
result = data.filter((v, i, a) => i !== a.lastIndexOf(v));
console.log(result);
You can use an empty object as a map to easily check if the item has been found before and then use Array#filter to remove the ones you don't want.
var list = ["a", "a", "b", "c", "d", "e"];
var occurences = {};
var filteredList = list.filter(function(item) {
if (item in occurences) return true; // if it has already been registered, add it to the new list
occurences[item] = 1; // register the item
return false; // ignore it on the new list
});
console.log(filteredList);
Shorthand version
let list = ["a", "a", "b", "c", "d", "e"], occurences = {};
list = list.filter(item => item in occurences ? 1 : occurences[item] = 1 && 0);
console.log(list);
you can simply use shift method checkout it here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/shift
I have two arrays (arr1 & arr2) like this
var arr1 = ["A","B","C"];
var arr2 = [["A","aa"], ["A","ab"], ["A","ac"],["B","ba"],["B","bb"],["B","bc"],["C","ca"],["C","cb"]];
I want to group them together into 3rd array in javascript based on the values of first array. Desired Output:
arr3 = [ ["A",["aa","ab","ac"]], ["B",["ba","bb","bc"] ], ["C",["ca","cb"]] ]
NOTE: I had arr2 to begin with and was able to retrieve first value and remove duplicates into arr1.
Please advise.
Try like this
var arr1 = ["A", "B", "C"];
var arr2 = [
["A", "aa"],
["A", "ab"],
["A", "ac"],
["B", "ba"],
["B", "bb"],
["B", "bc"],
["C", "ca"],
["C", "cb"]
];
var newVal = arr1.map(function(x) {
var filter = arr2.filter(function(y) {
return y[0] == x;
}).map(function(y) {
return y[1];
});
return [x, filter];
})
console.log(newVal);
DEMO
NOTE: I had arr2 to begin with and was able to retrieve first value and remove duplicates into arr1.
Rather than creating arr1 as a middle step, I would probably create an object as the middle step:
var obj = arr2.reduce(function(a,b){
if (!a[b[0]]) a[b[0]] = [];
a[b[0]].push(b[1]);
return a;
},{});
// obj is now {"A":["aa","ab","ac"],"B":["ba","bb","bc"],"C":["ca","cb"]}
To convert that object to your desired output array:
var arr3 = Object.keys(obj).map(function(v) { return [v, obj[v]]; });
// [["A",["aa","ab","ac"]],["B",["ba","bb","bc"]],["C",["ca","cb"]]]
If you actually need the arr1 array for something else then:
var arr1 = Object.keys(obj);
// ["A", "B", "C"]
But notice that obj is quite useful for further processing, because if you need to get the values associated with "B" you don't need to search through an array again, you can simply say obj["B"] (which will give the array ["ba","bb","bc"]). So the second "B" value is obj["B"][1].
Further reading:
.reduce()
.map()
Object.keys()
In playing with jQuery's utility method, jQuery.map(), I noticed that an undefined return value is omitted from the returned array. What is the reason for this?
var letters = ['a', undefined, 'c', undefined, 'e'];
console.log(letters); //["a", undefined, "c", undefined, "e"]
console.log(letters.length); //5
var lettersMapped = $.map(letters, function(item, index){
var item = item;
return item;
});
console.log(lettersMapped); //["a", "c", "e"]
console.log(lettersMapped.length); //3
Per the documentation for jQuery.map:
The function can return:
the translated value, which will be mapped to the resulting array
null or undefined, to remove the item
an array of values, which will be flattened into the full array
In other words, this is the expected behaviour of jQuery.map.
I wanted to ask if there is some kind of utility function which offers array joining while providing an index. Maybe Prototype of jQuery provides this, if not, I will write it on my own :)
What I expect is something like
var array= ["a", "b", "c", "d"];
function Array.prototype.join(seperator [, startIndex, endIndex]){
// code
}
so that array.join("-", 1, 2) would return "b-c"
Is there this kind of utility function in an pretty common Javascript Library?
Regards
globalworming
It works native
["a", "b", "c", "d"].slice(1,3).join("-") //b-c
If you want it to behave like your definition you could use it that way:
Array.prototype.myJoin = function(seperator,start,end){
if(!start) start = 0;
if(!end) end = this.length - 1;
end++;
return this.slice(start,end).join(seperator);
};
var arr = ["a", "b", "c", "d"];
arr.myJoin("-",2,3) //c-d
arr.myJoin("-") //a-b-c-d
arr.myJoin("-",1) //b-c-d
Just slice the array you want out, then join it manually.
var array= ["a", "b", "c", "d"];
var joinedArray = array.slice(1, 3).join("-");
Note: slice() doesn't include the last index specified, so (1, 3) is equivalent to (1, 2).
I have an array:
array = [..., "Hello", "World", "Again", ...]
How could I check if "World" is in the array?
Then remove it if it exists?
And have a reference to "World"?
Sometimes maybe I wanna match a word with a regexp and in that case I won't know the exact string so I need to have a reference to the matched String. But in this case I know for sure it's "World" which makes it simpler.
Thanks for the suggestions. I found a cool way to do it:
http://documentcloud.github.com/underscore
filter() is also an option:
arr = [..., "Hello", "World", "Again", ...]
newArr = arr.filter (word) -> word isnt "World"
array.indexOf("World") will get the index of "World" or -1 if it doesn't exist. array.splice(indexOfWorld, 1) will remove "World" from the array.
For this is such a natural need, I often prototype my arrays with an remove(args...) method.
My suggestion is to write this somewhere:
Array.prototype.remove = (args...) ->
output = []
for arg in args
index = #indexOf arg
output.push #splice(index, 1) if index isnt -1
output = output[0] if args.length is 1
output
And use like this anywhere:
array = [..., "Hello", "World", "Again", ...]
ref = array.remove("World")
alert array # [..., "Hello", "Again", ...]
alert ref # "World"
This way you can also remove multiple items at the same time:
array = [..., "Hello", "World", "Again", ...]
ref = array.remove("Hello", "Again")
alert array # [..., "World", ...]
alert ref # ["Hello", "Again"]
Checking if "World" is in array:
"World" in array
Removing if exists
array = (x for x in array when x != 'World')
or
array = array.filter (e) -> e != 'World'
Keeping reference (that's the shortest I've found - !.push is always false since .push > 0)
refs = []
array = array.filter (e) -> e != 'World' || !refs.push e
Try this :
filter = ["a", "b", "c", "d", "e", "f", "g"]
#Remove "b" and "d" from the array in one go
filter.splice(index, 1) for index, value of filter when value in ["b", "d"]
A combination of a few answers:
Array::remove = (obj) ->
#filter (el) -> el isnt obj
_.without() function from the underscorejs library is a good and clean option in case you want to get a new array :
_.without([1, 2, 1, 0, 3, 1, 4], 0, 1)
[2, 3, 4]
CoffeeScript + jQuery:
remove one, not all
arrayRemoveItemByValue = (arr,value) ->
r=$.inArray(value, arr)
unless r==-1
arr.splice(r,1)
# return
arr
console.log arrayRemoveItemByValue(['2','1','3'],'3')