Compare Optional Bool variable doesn't work - arrays

I have to create a 2D Array of Optional Bool type and compare the value inside it but I can't.
The first time I try to declare in this way:
var Answ = [[Bool?]] ()
var Page = 0
for i in 0...4
{
if Answ[Page][i] == true
{...}
else if Answ[Page][I] == false
{...}
else
{...}
}
...
but when I launch the program, it says:
index out of range
when Xcode compares the Answ[Page][i] with the value true.
So, I try to modify the code and declare the array in this way:
var Answ = Array (repeating: Array (repeating: Bool?.self , count: 5), count: 40)
var Page = 0
for i in 0...4
{
if Answ[Page][i] == true
{...}
else if Answ[Page][I] == false
{...}
else
{...}
}
...
but at the same point, (if Answ[Page][i] == true) throws this error:
Binary operator '==' cannot be applied to operands of type 'Bool?.Type' (aka 'optional.Type') and 'Bool'"
Moreover, in other points of the code where I try to set a value of the array as true/false (Answ[Page][2] = true), Xcode says this:
cannot assign value of type 'Bool' to type 'Bool?.Type' (Aka'Optional.Type')
Can someone help me, please? Thank you in advance.
I found this topic:
Checking the value of an Optional Bool
but it didn't help me much.

You can compare optional bools as in the Q&A that you linked to. The problem is that
var Answ = Array (repeating: Array (repeating: Bool?.self , count: 5), count: 40)
creates a (nested) array of Bool?.self, which is the type of an optional bool, not a value of that type.
What you want is a (nested) array of Bool? values, initialized to nil:
var answers: [[Bool?]] = Array(repeating: Array(repeating: nil , count: 5), count: 40)
or alternatively:
var answers = Array(repeating: Array(repeating: Bool?.none , count: 5), count: 40)

You should provide a fallback value with ??.
By the way, you don't need to write == false or == true, it's redundant.
if Answ[Page][i] ?? false {
  [...]
}

There are several issues with your code. First of all, don't use manual indexing in a for loop, rather use for ... in to have the indexes automatically handled for you. Secondly, a better solution for handling optional booleans is to safely unwrap the value using optional binding and then check the non-optional value. You also don't need to write if bool == true, if bool has the same meaning.
Also please make sure you conform to the Swift naming convention, which is lower-camelCase for variable names.
var answ = [[Bool?]] ()
var page = 0
for ans in answ[page]{
if let unwrappedAns = ans {
if unwrappedAns {
// answ[page][i] = true
} else {
}
} else {
//answ[page][i] = ans is nil
}
}
If you actually want to iterate through the whole array of arrays, this is one safe way for doing so:
for page in answ {
for ans in page {
//here ans = Answ[Page][i] when compared to the code in your question
if let unwrappedAns = ans {
if unwrappedAns {
} else {
}
} else {
//ans is nil
}
}
}

Related

How to find an array in an object of arrays [duplicate]

I'd like to compare two arrays... ideally, efficiently. Nothing fancy, just true if they are identical, and false if not. Not surprisingly, the comparison operator doesn't seem to work.
var a1 = [1,2,3];
var a2 = [1,2,3];
console.log(a1==a2); // Returns false
console.log(JSON.stringify(a1)==JSON.stringify(a2)); // Returns true
JSON encoding each array does, but is there a faster or "better" way to simply compare arrays without having to iterate through each value?
To compare arrays, loop through them and compare every value:
Comparing arrays:
// Warn if overriding existing method
if(Array.prototype.equals)
console.warn("Overriding existing Array.prototype.equals. Possible causes: New API defines the method, there's a framework conflict or you've got double inclusions in your code.");
// attach the .equals method to Array's prototype to call it on any array
Array.prototype.equals = function (array) {
// if the other array is a falsy value, return
if (!array)
return false;
// if the argument is the same array, we can be sure the contents are same as well
if(array === this)
return true;
// compare lengths - can save a lot of time
if (this.length != array.length)
return false;
for (var i = 0, l=this.length; i < l; i++) {
// Check if we have nested arrays
if (this[i] instanceof Array && array[i] instanceof Array) {
// recurse into the nested arrays
if (!this[i].equals(array[i]))
return false;
}
else if (this[i] != array[i]) {
// Warning - two different object instances will never be equal: {x:20} != {x:20}
return false;
}
}
return true;
}
// Hide method from for-in loops
Object.defineProperty(Array.prototype, "equals", {enumerable: false});
Usage:
[1, 2, [3, 4]].equals([1, 2, [3, 2]]) === false;
[1, "2,3"].equals([1, 2, 3]) === false;
[1, 2, [3, 4]].equals([1, 2, [3, 4]]) === true;
[1, 2, 1, 2].equals([1, 2, 1, 2]) === true;
You may say "But it is much faster to compare strings - no loops..." well, then you should note there ARE loops. First recursive loop that converts Array to string and second, that compares two strings. So this method is faster than use of string.
I believe that larger amounts of data should be always stored in arrays, not in objects. However if you use objects, they can be partially compared too.
Here's how:
Comparing objects:
I've stated above, that two object instances will never be equal, even if they contain same data at the moment:
({a:1, foo:"bar", numberOfTheBeast: 666}) == ({a:1, foo:"bar", numberOfTheBeast: 666}) //false
This has a reason, since there may be, for example private variables within objects.
However, if you just use object structure to contain data, comparing is still possible:
Object.prototype.equals = function(object2) {
//For the first loop, we only check for types
for (propName in this) {
//Check for inherited methods and properties - like .equals itself
//https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty
//Return false if the return value is different
if (this.hasOwnProperty(propName) != object2.hasOwnProperty(propName)) {
return false;
}
//Check instance type
else if (typeof this[propName] != typeof object2[propName]) {
//Different types => not equal
return false;
}
}
//Now a deeper check using other objects property names
for(propName in object2) {
//We must check instances anyway, there may be a property that only exists in object2
//I wonder, if remembering the checked values from the first loop would be faster or not
if (this.hasOwnProperty(propName) != object2.hasOwnProperty(propName)) {
return false;
}
else if (typeof this[propName] != typeof object2[propName]) {
return false;
}
//If the property is inherited, do not check any more (it must be equa if both objects inherit it)
if(!this.hasOwnProperty(propName))
continue;
//Now the detail check and recursion
//This returns the script back to the array comparing
/**REQUIRES Array.equals**/
if (this[propName] instanceof Array && object2[propName] instanceof Array) {
// recurse into the nested arrays
if (!this[propName].equals(object2[propName]))
return false;
}
else if (this[propName] instanceof Object && object2[propName] instanceof Object) {
// recurse into another objects
//console.log("Recursing to compare ", this[propName],"with",object2[propName], " both named \""+propName+"\"");
if (!this[propName].equals(object2[propName]))
return false;
}
//Normal value comparison for strings and numbers
else if(this[propName] != object2[propName]) {
return false;
}
}
//If everything passed, let's say YES
return true;
}
However, remember that this one is to serve in comparing JSON like data, not class instances and other stuff. If you want to compare more complicated objects, look at this answer and it's super long function.
To make this work with Array.equals you must edit the original function a little bit:
...
// Check if we have nested arrays
if (this[i] instanceof Array && array[i] instanceof Array) {
// recurse into the nested arrays
if (!this[i].equals(array[i]))
return false;
}
/**REQUIRES OBJECT COMPARE**/
else if (this[i] instanceof Object && array[i] instanceof Object) {
// recurse into another objects
//console.log("Recursing to compare ", this[propName],"with",object2[propName], " both named \""+propName+"\"");
if (!this[i].equals(array[i]))
return false;
}
else if (this[i] != array[i]) {
...
I made a little test tool for both of the functions.
Bonus: Nested arrays with indexOf and contains
Samy Bencherif has prepared useful functions for the case you're searching for a specific object in nested arrays, which are available here: https://jsfiddle.net/SamyBencherif/8352y6yw/
While this only works for scalar arrays (see note below), it is short code:
array1.length === array2.length && array1.every(function(value, index) { return value === array2[index]})
Same as above but in ECMAScript 6 / CoffeeScript / TypeScript with Arrow Functions:
array1.length === array2.length && array1.every((value, index) => value === array2[index])
(Note: 'scalar' here means values that can be compared directly using === . So: numbers, strings, objects by reference, functions by reference. See the MDN reference for more info about the comparison operators).
UPDATE
From what I read in the comments, sorting the array and comparing may give accurate result:
const array2Sorted = array2.slice().sort();
array1.length === array2.length && array1.slice().sort().every(function(value, index) {
return value === array2Sorted[index];
});
Eg:
array1 = [2,3,1,4];
array2 = [1,2,3,4];
Then the above code would return true
I like to use the Underscore library for array/object heavy coding projects ... in Underscore and Lodash whether you're comparing arrays or objects it just looks like this:
_.isEqual(array1, array2) // returns a boolean
_.isEqual(object1, object2) // returns a boolean
Underscore isEqual docs
Lodash isEqual docs
This I think is the simplest way to do it using JSON stringify, and it may be the best solution in some situations:
JSON.stringify(a1) === JSON.stringify(a2);
This converts the objects a1 and a2 into strings so they can be compared. The order is important in most cases, for that can sort the object using a sort algorithm shown in one of the above answers.
Please do note that you are no longer comparing the object but the string representation of the object. It may not be exactly what you want.
In the spirit of the original question:
I'd like to compare two arrays... ideally, efficiently. Nothing
fancy, just true if they are identical, and false if not.
I have been running performance tests on some of the more simple suggestions proposed here with the following results (fast to slow):
while (67%) by Tim Down
var i = a1.length;
while (i--) {
if (a1[i] !== a2[i]) return false;
}
return true
every (69%) by user2782196
a1.every((v,i)=> v === a2[i]);
reduce (74%) by DEIs
a1.reduce((a, b) => a && a2.includes(b), true);
join & toString (78%) by Gaizka Allende & vivek
a1.join('') === a2.join('');
a1.toString() === a2.toString();
half toString (90%) by Victor Palomo
a1 == a2.toString();
stringify (100%) by radtek
JSON.stringify(a1) === JSON.stringify(a2);
Note the examples below assumes the arrays are sorted, single-dimensional arrays. .length comparison has been removed for a common benchmark (add a1.length === a2.length to any of the suggestions and you will get a ~10% performance boost). Choose whatever solutions that works best for you knowing the speed and limitation of each.
The Practical Way
I think it's wrong to say a particular implementation is "The Right Way™" if it's only "right" ("correct") in contrast to a "wrong" solution. Tomáš's solution is a clear improvement over string-based array comparison, but that doesn't mean it's objectively "right". What is right anyway? Is it the fastest? Is it the most flexible? Is it the easiest to comprehend? Is it the quickest to debug? Does it use the least operations? Does it have any side effects? No one solution can have the best of all the things.
Tomáš's could say his solution is fast but I would also say it is needlessly complicated. It tries to be an all-in-one solution that works for all arrays, nested or not. In fact, it even accepts more than just arrays as an input and still attempts to give a "valid" answer.
Generics offer reusability
My answer will approach the problem differently. I'll start with a generic arrayCompare procedure that is only concerned with stepping through the arrays. From there, we'll build our other basic comparison functions like arrayEqual and arrayDeepEqual, etc
// arrayCompare :: (a -> a -> Bool) -> [a] -> [a] -> Bool
const arrayCompare = f => ([x,...xs]) => ([y,...ys]) =>
x === undefined && y === undefined
? true
: Boolean (f (x) (y)) && arrayCompare (f) (xs) (ys)
In my opinion, the best kind of code doesn't even need comments, and this is no exception. There's so little happening here that you can understand the behaviour of this procedure with almost no effort at all. Sure, some of the ES6 syntax might seem foreign to you now, but that's only because ES6 is relatively new.
As the type suggests, arrayCompare takes comparison function, f, and two input arrays, xs and ys. For the most part, all we do is call f (x) (y) for each element in the input arrays. We return an early false if the user-defined f returns false – thanks to &&'s short-circuit evaluation. So yes, this means the comparator can stop iteration early and prevent looping through the rest of the input array when unnecessary.
Strict comparison
Next, using our arrayCompare function, we can easily create other functions we might need. We'll start with the elementary arrayEqual …
// equal :: a -> a -> Bool
const equal = x => y =>
x === y // notice: triple equal
// arrayEqual :: [a] -> [a] -> Bool
const arrayEqual =
arrayCompare (equal)
const xs = [1,2,3]
const ys = [1,2,3]
console.log (arrayEqual (xs) (ys)) //=> true
// (1 === 1) && (2 === 2) && (3 === 3) //=> true
const zs = ['1','2','3']
console.log (arrayEqual (xs) (zs)) //=> false
// (1 === '1') //=> false
Simple as that. arrayEqual can be defined with arrayCompare and a comparator function that compares a to b using === (for strict equality).
Notice that we also define equal as it's own function. This highlights the role of arrayCompare as a higher-order function to utilize our first order comparator in the context of another data type (Array).
Loose comparison
We could just as easily defined arrayLooseEqual using a == instead. Now when comparing 1 (Number) to '1' (String), the result will be true …
// looseEqual :: a -> a -> Bool
const looseEqual = x => y =>
x == y // notice: double equal
// arrayLooseEqual :: [a] -> [a] -> Bool
const arrayLooseEqual =
arrayCompare (looseEqual)
const xs = [1,2,3]
const ys = ['1','2','3']
console.log (arrayLooseEqual (xs) (ys)) //=> true
// (1 == '1') && (2 == '2') && (3 == '3') //=> true
Deep comparison (recursive)
You've probably noticed that this is only shallow comparison tho. Surely Tomáš's solution is "The Right Way™" because it does implicit deep comparison, right ?
Well our arrayCompare procedure is versatile enough to use in a way that makes a deep equality test a breeze …
// isArray :: a -> Bool
const isArray =
Array.isArray
// arrayDeepCompare :: (a -> a -> Bool) -> [a] -> [a] -> Bool
const arrayDeepCompare = f =>
arrayCompare (a => b =>
isArray (a) && isArray (b)
? arrayDeepCompare (f) (a) (b)
: f (a) (b))
const xs = [1,[2,[3]]]
const ys = [1,[2,['3']]]
console.log (arrayDeepCompare (equal) (xs) (ys)) //=> false
// (1 === 1) && (2 === 2) && (3 === '3') //=> false
console.log (arrayDeepCompare (looseEqual) (xs) (ys)) //=> true
// (1 == 1) && (2 == 2) && (3 == '3') //=> true
Simple as that. We build a deep comparator using another higher-order function. This time we're wrapping arrayCompare using a custom comparator that will check if a and b are arrays. If so, reapply arrayDeepCompare otherwise compare a and b to the user-specified comparator (f). This allows us to keep the deep comparison behavior separate from how we actually compare the individual elements. Ie, like the example above shows, we can deep compare using equal, looseEqual, or any other comparator we make.
Because arrayDeepCompare is curried, we can partially apply it like we did in the previous examples too
// arrayDeepEqual :: [a] -> [a] -> Bool
const arrayDeepEqual =
arrayDeepCompare (equal)
// arrayDeepLooseEqual :: [a] -> [a] -> Bool
const arrayDeepLooseEqual =
arrayDeepCompare (looseEqual)
To me, this already a clear improvement over Tomáš's solution because I can explicitly choose a shallow or deep comparison for my arrays, as needed.
Object comparison (example)
Now what if you have an array of objects or something ? Maybe you want to consider those arrays as "equal" if each object has the same id value …
// idEqual :: {id: Number} -> {id: Number} -> Bool
const idEqual = x => y =>
x.id !== undefined && x.id === y.id
// arrayIdEqual :: [a] -> [a] -> Bool
const arrayIdEqual =
arrayCompare (idEqual)
const xs = [{id:1}, {id:2}]
const ys = [{id:1}, {id:2}]
console.log (arrayIdEqual (xs) (ys)) //=> true
// (1 === 1) && (2 === 2) //=> true
const zs = [{id:1}, {id:6}]
console.log (arrayIdEqual (xs) (zs)) //=> false
// (1 === 1) && (2 === 6) //=> false
Simple as that. Here I've used vanilla JS objects, but this type of comparator could work for any object type; even your custom objects. Tomáš's solution would need to be completely reworked to support this kind of equality test
Deep array with objects? Not a problem. We built highly versatile, generic functions, so they'll work in a wide variety of use cases.
const xs = [{id:1}, [{id:2}]]
const ys = [{id:1}, [{id:2}]]
console.log (arrayCompare (idEqual) (xs) (ys)) //=> false
console.log (arrayDeepCompare (idEqual) (xs) (ys)) //=> true
Arbitrary comparison (example)
Or what if you wanted to do some other kind of kind of completely arbitrary comparison ? Maybe I want to know if each x is greater than each y …
// gt :: Number -> Number -> Bool
const gt = x => y =>
x > y
// arrayGt :: [a] -> [a] -> Bool
const arrayGt = arrayCompare (gt)
const xs = [5,10,20]
const ys = [2,4,8]
console.log (arrayGt (xs) (ys)) //=> true
// (5 > 2) && (10 > 4) && (20 > 8) //=> true
const zs = [6,12,24]
console.log (arrayGt (xs) (zs)) //=> false
// (5 > 6) //=> false
Less is More
You can see we're actually doing more with less code. There's nothing complicated about arrayCompare itself and each of the custom comparators we've made have a very simple implementation.
With ease, we can define exactly how we wish for two arrays to be compared — shallow, deep, strict, loose, some object property, or some arbitrary computation, or any combination of these — all using one procedure, arrayCompare. Maybe even dream up a RegExp comparator ! I know how kids love those regexps …
Is it the fastest? Nope. But it probably doesn't need to be either. If speed is the only metric used to measure the quality of our code, a lot of really great code would get thrown away — That's why I'm calling this approach The Practical Way. Or maybe to be more fair, A Practical Way. This description is suitable for this answer because I'm not saying this answer is only practical in comparison to some other answer; it is objectively true. We've attained a high degree of practicality with very little code that's very easy to reason about. No other code can say we haven't earned this description.
Does that make it the "right" solution for you ? That's up for you to decide. And no one else can do that for you; only you know what your needs are. In almost all cases, I value straightforward, practical, and versatile code over clever and fast kind. What you value might differ, so pick what works for you.
Edit
My old answer was more focused on decomposing arrayEqual into tiny procedures. It's an interesting exercise, but not really the best (most practical) way to approach this problem. If you're interested, you can see this revision history.
It's unclear what you mean by "identical". For example, are the arrays a and b below identical (note the nested arrays)?
var a = ["foo", ["bar"]], b = ["foo", ["bar"]];
Here's an optimized array comparison function that compares corresponding elements of each array in turn using strict equality and does not do recursive comparison of array elements that are themselves arrays, meaning that for the above example, arraysIdentical(a, b) would return false. It works in the general case, which JSON- and join()-based solutions will not:
function arraysIdentical(a, b) {
var i = a.length;
if (i != b.length) return false;
while (i--) {
if (a[i] !== b[i]) return false;
}
return true;
};
Building off Tomáš Zato's answer, I agree that just iterating through the arrays is the fastest. Additionally (like others have already stated), the function should be called equals/equal, not compare. In light of this, I modified the function to handle comparing arrays for similarity - i.e. they have the same elements, but out of order - for personal use, and thought I'd throw it on here for everyone to see.
Array.prototype.equals = function (array, strict) {
if (!array)
return false;
if (arguments.length == 1)
strict = true;
if (this.length != array.length)
return false;
for (var i = 0; i < this.length; i++) {
if (this[i] instanceof Array && array[i] instanceof Array) {
if (!this[i].equals(array[i], strict))
return false;
}
else if (strict && this[i] != array[i]) {
return false;
}
else if (!strict) {
return this.sort().equals(array.sort(), true);
}
}
return true;
}
This function takes an additional parameter of strict that defaults to true. This strict parameter defines if the arrays need to be wholly equal in both contents and the order of those contents, or simply just contain the same contents.
Example:
var arr1 = [1, 2, 3, 4];
var arr2 = [2, 1, 4, 3]; // Loosely equal to 1
var arr3 = [2, 2, 3, 4]; // Not equal to 1
var arr4 = [1, 2, 3, 4]; // Strictly equal to 1
arr1.equals(arr2); // false
arr1.equals(arr2, false); // true
arr1.equals(arr3); // false
arr1.equals(arr3, false); // false
arr1.equals(arr4); // true
arr1.equals(arr4, false); // true
I've also written up a quick jsfiddle with the function and this example:
http://jsfiddle.net/Roundaround/DLkxX/
On the same lines as JSON.encode is to use join().
function checkArrays( arrA, arrB ){
//check if lengths are different
if(arrA.length !== arrB.length) return false;
//slice so we do not effect the original
//sort makes sure they are in order
//join makes it a string so we can do a string compare
var cA = arrA.slice().sort().join(",");
var cB = arrB.slice().sort().join(",");
return cA===cB;
}
var a = [1,2,3,4,5];
var b = [5,4,3,2,1];
var c = [1,2,3,4];
var d = [1,2,3,4,6];
var e = ["1","2","3","4","5"]; //will return true
console.log( checkArrays(a,b) ); //true
console.log( checkArrays(a,c) ); //false
console.log( checkArrays(a,d) ); //false
console.log( checkArrays(a,e) ); //true
Only problem is if you care about types which the last comparison tests.
If you care about types, you will have to loop.
function checkArrays( arrA, arrB ){
//check if lengths are different
if(arrA.length !== arrB.length) return false;
//slice so we do not effect the orginal
//sort makes sure they are in order
var cA = arrA.slice().sort();
var cB = arrB.slice().sort();
for(var i=0;i<cA.length;i++){
if(cA[i]!==cB[i]) return false;
}
return true;
}
var a = [1,2,3,4,5];
var b = [5,4,3,2,1];
var c = [1,2,3,4];
var d = [1,2,3,4,6];
var e = ["1","2","3","4","5"];
console.log( checkArrays(a,b) ); //true
console.log( checkArrays(a,c) ); //false
console.log( checkArrays(a,d) ); //false
console.log( checkArrays(a,e) ); //false
If the order should remain the same, than it is just a loop, no sort is needed.
function checkArrays( arrA, arrB ){
//check if lengths are different
if(arrA.length !== arrB.length) return false;
for(var i=0;i<arrA.length;i++){
if(arrA[i]!==arrB[i]) return false;
}
return true;
}
var a = [1,2,3,4,5];
var b = [5,4,3,2,1];
var c = [1,2,3,4];
var d = [1,2,3,4,6];
var e = ["1","2","3","4","5"];
console.log( checkArrays(a,a) ); //true
console.log( checkArrays(a,b) ); //false
console.log( checkArrays(a,c) ); //false
console.log( checkArrays(a,d) ); //false
console.log( checkArrays(a,e) ); //false
In my case compared arrays contain only numbers and strings. This function will show you if arrays contain same elements.
function are_arrs_match(arr1, arr2){
return arr1.sort().toString() === arr2.sort().toString()
}
Let's test it!
arr1 = [1, 2, 3, 'nik']
arr2 = ['nik', 3, 1, 2]
arr3 = [1, 2, 5]
console.log (are_arrs_match(arr1, arr2)) //true
console.log (are_arrs_match(arr1, arr3)) //false
Even though this has a lot of answers, one that I believe to be of help:
const newArray = [ ...new Set( [...arr1, ...arr2] ) ]
It is not stated in the question how the structure of the array is going to look like, so If you know for sure that you won't have nested arrays nor objects in you array (it happened to me, that's why I came to this answer) the above code will work.
What happens is that we use spread operator ( ... ) to concat both arrays, then we use Set to eliminate any duplicates. Once you have that you can compare their sizes, if all three arrays have the same size you are good to go.
This answer also ignores the order of elements, as I said, the exact situation happened to me, so maybe someone in the same situation might end up here (as I did).
Edit1.
Answering Dmitry Grinko's question: "Why did you use spread operator ( ... ) here - ...new Set ? It doesn't work"
Consider this code:
const arr1 = [ 'a', 'b' ]
const arr2 = [ 'a', 'b', 'c' ]
const newArray = [ new Set( [...arr1, ...arr2] ) ]
console.log(newArray)
You'll get
[ Set { 'a', 'b', 'c' } ]
In order to work with that value you'd need to use some Set properties (see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set).
On the other hand, when you use this code:
const arr1 = [ 'a', 'b' ]
const arr2 = [ 'a', 'b', 'c' ]
const newArray = [ ...new Set( [...arr1, ...arr2] ) ]
console.log(newArray)
You'll get
[ 'a', 'b', 'c' ]
That's the difference, the former would give me a Set, it would work too as I could get the size of that Set, but the latter gives me the array I need, what's more direct to the resolution.
Shortest
For an array of numbers try:
a1==''+a2
var a1 = [1,2,3];
var a2 = [1,2,3];
console.log( a1==''+a2 )
Note: this method will not work when the array also contains strings, e.g. a2 = [1, "2,3"].
You can simply use isEqual from lodash library. It is very efficient and clean.
import isEqual from "lodash/isEqual";
const isTwoArraysEqual = isEqual(array1, array2);
Your code will not handle the case appropriately when both arrays have same elements but not in same order.
Have a look at my code with your example which compares two arrays whose elements are numbers, you might modify or extend it for other element types (by utilising .join() instead of .toString()).
var a1 = [1,2,3];
var a2 = [1,2,3];
const arraysAreEqual = a1.sort().toString()==a2.sort().toString();
// true if both arrays have same elements else false
console.log(arraysAreEqual);
There are many complicated long answers in here, so I just want to contribute one very simple answer: use toString() to turn an array into a simple comma-separated string which you can easily compare with ===
let a = [1, 2, 3]
let b = [1, 2, 3]
let c = [4, 2, 3]
console.log(a.toString()) // this outputs "1,2,3"
console.log(a.toString() === b.toString()) // this outputs true because "1,2,3" === "1,2,3"
console.log(a.toString() === c.toString()) // this outputs false because "1,2,3" != "4,2,3"
Here you go,
const a = [1, 2, 3]
const b = [1, 2, 3, 4, 5]
const diff = b.filter(e => !a.includes(e))
console.log(diff)
Most of the above answers dosen't work for unordered list.
This works for unordered lists too.
const a = [3, 2, 1]
const b = [1, 2, 3, 4, 5]
const diff = b.filter(e => !a.includes(e))
console.log(diff)
If size of a is greater than b,
const a = [1, 2, 3, 4, 5]
const b = [3, 2, 1]
const diff = a.length > b.length ? a.filter(e => !b.includes(e)) : b.filter(e => !a.includes(e))
console.log(diff)
Code Golfing
There are plenty of answers showing how to compare arrays efficiently.
Below is the shortest way to compare two int or (string) arrays, measured in bytes of code.
const a = [1, 2, 3]
const b = [1, 2, 3]
console.log("1. ", a.join() == b.join())
console.log("2. ", a.join() == [].join())
console.log("3. ", 1 + a == 1 + b)
console.log("4. ", 1 + [] == 1 + b)
// even shorter
console.log("4. b) ", a == "" + b)
// false positives (see flaws)
console.log("5. ", 1 + ["3"] == 1 + [3]) // type differences
console.log("6. ", 1 + ["1,2"] == 1 + ["1", "2"])
Explanation
This works because when using the + operator, the types are automatically converted to allow concatenation. In this case, the 1 and the [1, 2, 3] are both converted to a string.
Internally, JavaScript uses [1, 2, 3].join() to convert the array to a string and then adds them resulting in 11,2,3. When doing this on both arrays, one can simply use === or == to compare the two strings.
Flaws
Using this technique, the comparison does not care if the elements in the arrays to be compared are of different types. [1, 2] will be equal to ["1", "2"] because of the string conversion.
EDIT: As pointed out in the comments, comparing string arrays can produce false positives, such as ["1,2"] being 'equal' to ["1", "2"]. This is of no concern if you are sure these never occur (e.g. in many code golfing challenges).
Disclaimer
While this is useful for code golfing, it should probably not be used in production code. The two flaws pointed out aren't helping that either.
Lot of good answers here. This is how I usually do it -
if ( arr1.length === arr2.length && arr1.every((a1) => arr2.includes(a1)) ) {
// logic
}
every() will only return true if all elements pass the given camparison
logic. If it encounters a false, in any iteration, it terminates and
returns false.
Time complexity will be O(n*m).
Here is a Typescript version:
//https://stackoverflow.com/a/16436975/2589276
export function arraysEqual<T>(a: Array<T>, b: Array<T>): boolean {
if (a === b) return true
if (a == null || b == null) return false
if (a.length != b.length) return false
for (var i = 0; i < a.length; ++i) {
if (a[i] !== b[i]) return false
}
return true
}
//https://stackoverflow.com/a/16436975/2589276
export function arraysDeepEqual<T>(a: Array<T>, b: Array<T>): boolean {
return JSON.stringify(a) === JSON.stringify(b)
}
Some test cases for mocha:
it('arraysEqual', function () {
let a = [1,2]
let b = [1,2]
let c = [2,3]
let d = [2, 3]
let e = ['car','apple','banana']
let f = ['car','apple','banana']
let g = ['car','apple','banan8']
expect(arraysEqual(a, b)).to.equal(true)
expect(arraysEqual(c, d)).to.equal(true)
expect(arraysEqual(a, d)).to.equal(false)
expect(arraysEqual(e, f)).to.equal(true)
expect(arraysEqual(f, g)).to.equal(false)
})
it('arraysDeepEqual', function () {
let a = [1,2]
let b = [1,2]
let c = [2,3]
let d = [2, 3]
let e = ['car','apple','banana']
let f = ['car','apple','banana']
let g = ['car','apple','banan8']
let h = [[1,2],'apple','banan8']
let i = [[1,2],'apple','banan8']
let j = [[1,3],'apple','banan8']
expect(arraysDeepEqual(a, b)).to.equal(true)
expect(arraysDeepEqual(c, d)).to.equal(true)
expect(arraysDeepEqual(a, d)).to.equal(false)
expect(arraysDeepEqual(e, f)).to.equal(true)
expect(arraysDeepEqual(f, g)).to.equal(false)
expect(arraysDeepEqual(h, i)).to.equal(true)
expect(arraysDeepEqual(h, j)).to.equal(false)
})
There is a Stage 1 proposal, introduced in 2020, to allow for the easy comparison of arrays by adding Array.prototype.equals to the language. This is how it would work, without any libraries, monkeypatching, or any other code:
[1, 2, 3].equals([1, 2, 3]) // evaluates to true
[1, 2, undefined].equals([1, 2, 3]) // evaluates to false
[1, [2, [3, 4]]].equals([1, [2, [3, 4]]]) // evaluates to true
It's only a tentative proposal so far - TC39 will now "devote time to examining the problem space, solutions and cross-cutting concerns". If it makes it to stage 2, it has a good chance of eventually being integrated into the language proper.
If you are using a testing framework like Mocha with the Chai assertion library, you can use deep equality to compare arrays.
expect(a1).to.deep.equal(a2)
This should return true only if the arrays have equal elements at corresponding indices.
If they are two arrays of numbers or strings only, this is a quick one-line one
const array1 = [1, 2, 3];
const array2 = [1, 3, 4];
console.log(array1.join(',') === array2.join(',')) //false
const array3 = [1, 2, 3];
const array4 = [1, 2, 3];
console.log(array3.join(',') === array4.join(',')) //true
Another approach with very few code (using Array reduce and Array includes):
arr1.length == arr2.length && arr1.reduce((a, b) => a && arr2.includes(b), true)
If you want to compare also the equality of order:
arr1.length == arr2.length && arr1.reduce((a, b, i) => a && arr2[i], true)
The length check ensures that the set of elements in one array isn't just a subset of the other one.
The reducer is used to walk through one array and search for each item in other array. If one item isn't found the reduce function returns false.
In the first example it's being tested that an element is included
The second example check for the order too
We could do this the functional way, using every (https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/every)
function compareArrays(array1, array2) {
if (array1.length === array2.length)
return array1.every((a, index) => a === array2[index])
else
return false
}
// test
var a1 = [1,2,3];
var a2 = [1,2,3];
var a3 = ['a', 'r', 'r', 'a', 'y', '1']
var a4 = ['a', 'r', 'r', 'a', 'y', '2']
console.log(compareArrays(a1,a2)) // true
console.log(compareArrays(a1,a3)) // false
console.log(compareArrays(a3,a4)) // false
This compares 2 unsorted arrays:
function areEqual(a, b) {
if ( a.length != b.length) {
return false;
}
return a.filter(function(i) {
return !b.includes(i);
}).length === 0;
}
A simple approach:
function equals(a, b) {
if ((a && !b) || (!a && b) || (!a && !b) || (a.length !== b.length)) {
return false;
}
var isDifferent = a.some(function (element, index) {
return element !== b[index];
});
return !isDifferent;
}
Already some great answers.But i would like to share anther idea which has proven to be reliable in comparing arrays. We can compare two array using JSON.stringify ( ) . It will create a string out the the array and thus compare two obtained strings from two array for equality
JSON.stringify([1,{a:1},2]) == JSON.stringify([1,{a:1},2]) //true
JSON.stringify([1,{a:1},2]) == JSON.stringify([1,{a:2},2]) //false
JSON.stringify([1,{a:1},2]) == JSON.stringify([1,{a:2},[3,4],2]) //false
JSON.stringify([1,{a:1},[3,4],2]) == JSON.stringify([1,{a:2},[3,4],2]) //false
JSON.stringify([1,{a:2},[3,4],2]) == JSON.stringify([1,{a:2},[3,4],2]) //true
JSON.stringify([1,{a:2},[3,4],2]) == JSON.stringify([1,{a:2},[3,4,[5]],2]) //false
JSON.stringify([1,{a:2},[3,4,[4]],2]) == JSON.stringify([1,{a:2},[3,4,[5]],2]) //false
JSON.stringify([1,{a:2},[3,4,[5]],2]) == JSON.stringify([1,{a:2},[3,4,[5]],2]) //true
In a simple way uning stringify but at same time thinking in complex arrays:
**Simple arrays**:
var a = [1,2,3,4];
var b = [4,2,1,4];
JSON.stringify(a.sort()) === JSON.stringify(b.sort()) // true
**Complex arrays**:
var a = [{id:5,name:'as'},{id:2,name:'bes'}];
var b = [{id:2,name:'bes'},{id:5,name:'as'}];
JSON.stringify(a.sort(function(a,b) {return a.id - b.id})) === JSON.stringify(b.sort(function(a,b) {return a.id - b.id})) // true
**Or we can create a sort function**
function sortX(a,b) {
return a.id -b.id; //change for the necessary rules
}
JSON.stringify(a.sort(sortX)) === JSON.stringify(b.sort(sortX)) // true
Here a possibility for unsorted arrays and custom comparison:
const array1 = [1,3,2,4,5];
const array2 = [1,3,2,4,5];
const isInArray1 = array1.every(item => array2.find(item2 => item===item2))
const isInArray2 = array2.every(item => array1.find(item2 => item===item2))
const isSameArray = array1.length === array2.length && isInArray1 && isInArray2
console.log(isSameArray); //true
Simple
type Values = number | string;
/** Not sorted array */
function compare<Values>(a1: Array<Values>, a2: Array<Values>): boolean {
if (a1.length !== a2.length) {
return false;
}
/** Unique values */
const set1 = new Set<Values>(a1);
const set2 = new Set<Values>(a2);
if (set1.size !== set2.size) {
return false;
}
return [...set1].every((value) => [...set2].includes(value));
}
compare([1, 2, 3], [1, 2, 3]); // true
compare([1, 2, 3], [1, 3, 2]); // true
compare([1, 1, 1], [1, 2, 3]); // false
compare([1, 1, 2, 3], [1, 2, 3]); // false
/** Sorted arrays, faster method */
function compareSorted<Values>(a1: Array<Values>, a2: Array<Values>): boolean {
if (a1.length !== a2.length) {
return false;
}
/** Unique values */
const set1 = new Set<Values>(a1);
const set2 = new Set<Values>(a2);
if (set1.size !== set2.size) {
return false;
}
return [...set1].every((value, index) => value === [...set2][index]);
}
compareSorted([1, 2, 3], [1, 2, 3]); // true
compareSorted([1, 2, 3], [1, 3, 2]); // false
compareSorted([1, 1, 1], [1, 2, 3]); // false
compareSorted([1, 1, 2, 3], [1, 2, 3]); // false

Check if array contains element in Swift 4

I am trying to check if array categories contain number 1 as Int since categories = [Int]() for example categories = {1, 2, 3, 4, 5}
I have tried the below code which gives me error Binary operator '==' cannot be applied to operands of type 'Any' and 'Int'
if categories.contains (where: {$0 == 1}) {
// 1 is found
}
also tried it without the where and brackets as below which gives me the same error
if categories.contains { $0 == 1 } {
// 1 is found
}
I tried using just the element as below which gives me error Missing argument label 'where:' in call
if categories.contains(1) {
// 1 is found
}
How can I do that?
It seems like your category array is of type Any
Ways to fix it
You can declare your array as an Int array
var categories: [Int]
OR
You can change the following piece of code
if categories.contains { $0 == 1 } {
// 1 is found
}
to
if categories.contains { ($0 as! Int) == 1 } {
// 1 is found
}
Note: This method might cause your app to crash if your category array has an element other than of type Int
it is working See my output in PlayGround
Code used:
var categories : [Int] = [0,1,2,3,4,5,6,7,8,9]
if categories.contains(5)
{
print("Yes it contains")
}
else
{
print("it do not")
}
and also This condition is working
if categories.contains (where: {$0 == 1}) {
print("yes")
}
see your Array Declaration I think there is main Issue
Declaration 1 :
var categories = [Int]()
categories = [0,1,2,3,4,5,6,7,8,9]
Declaration 2 :
var categories : [Int] = [0,1,2,3,4,5,6,7,8,9]
Regarding error message
Binary operator '==' cannot be applied to operands of type 'Any' and 'Int'
Your array is not an Int array instead it contains Any so it needs typecasting before comparision. Declaration of array is also wrong use [] instead of {}. And typecast object as an int ($0 as! Int) == 1 (I'm using force casting here because I know its an Int array).
There are many ways to check if array contains any element.
1> Just try to get the index of element with guard if index is nil means array doesn't contain the element. Although you didn't declare array in right way still I'm considering it a valid array.
let categories: [Int] = [1, 2, 3, 4, 5]
guard categories.index(of: 1) != nil else {
print("Doesn't Contain")
return
}
print("Contains")
2> Use contains method
if (categories.contains(1)) {
print("Contains")
}
else {
print("Doesn't Contain")
}
3> Not Recommended for this case But still you can get this
let result = categories.filter({$0 == 1})
if result.count == 0 {
print("Doesn't Contain")
}
else {
print("Contains")
}
filter returns an array of element which matches with condition. So that if there are multiple 1 in array so it will give you an array of all elements. And $0 describes the object while enumerating the array.
4> Not Recommended for this case
let contains = categories.contains(where: {$0 == 1})
if contains {
print("Contains")
}
else {
print("Doesn't Contain")
}
Thanks to your comments made me check the declaration of the array and the problem was that was declared as [Any] after I get it's value from the UserDefaults. I have checked and found the solution on How do I save an Int array in Swift using NSUserDefaults?
// old declaration
let categories = userDefaults.array(forKey:"categories") ?? [Int]()
// new correct declaration
var categories = [Int]()
if let temp = userDefaults.array(forKey:"categories") as? [Int] {
categories = temp
}

Check whether integers in array are consecutive or in sequence

Is there any best method to check if elements in array are in consecutive order?
Eg:
[1,2,3,4,5] // returns true
[1,2,4,3,5] // returns false
Currently what I implement is to take difference of elements and if the diff is 1 then I say it is in consecutive order.
I'm looking for any improved approach. I think of adding extension to Array but not sure how to implement this.
Given your array
let list = [1,2,3,4,5]
you can use some Functional Programming magic
let consecutives = list.map { $0 - 1 }.dropFirst() == list.dropLast()
If this is a one-off question, then any little for-loop is fine, but it's an interesting problem to explore generic solutions. First, I'm assuming you mean that each element must be one greater than the one before, not just in order.
Let's build a generic way to answer "do all pairs of elements in this collection obey some rule." First, it'd be really nice to have a generic way to say "do all?"
extension Sequence {
func all(pass predicate: (Element) -> Bool) -> Bool {
// If nothing is false, everything is true
return !self.contains(where: { !predicate($0) })
}
}
This returns whether all elements of a sequence obey some rule.
Now we can ask the question: do all pair-wise elements of a collection obey some rule:
extension Collection {
func passesForConsecutiveValues(_ predicate:(Element, Element) -> Bool) -> Bool {
return zip(self, dropFirst()).all(pass: predicate)
}
}
zip(x, x.dropFirst() just creates "pair-wise elements", and then we ask "do they all satisfy our rule?" For example:
// Are all elements one more than their predecessor?
[1,2,4,5].passesForConsecutiveValues { $1 == $0 + 1 } // true
Now you may have noticed that I switched from Sequence to Collection in the middle there. Why? Because zip(x, x.dropFirst()) isn't defined on arbitrary sequences. You may only be allowed to iterate over a sequence once. Unfortunately there's no way to know; it's considered "special knowledge about the sequence" in the docs. Bleh. I miss Scala's TraversableOnce vs. Sequence that moves the requirement into the type.
That said, we absolutely can build this for Sequence. We just have to build a replacement for zip(x, x.dropFirst()). We'll call it pairwise and it'll return an iterator:
extension Sequence {
func pairwise() -> AnyIterator<(Element, Element)> {
var it = makeIterator()
guard var last_value = it.next() else { return AnyIterator{ return nil } }
return AnyIterator {
guard let value = it.next() else { return nil }
defer { last_value = value }
return (last_value, value)
}
}
}
And with that, we can build this on Sequence:
extension Sequence {
func passesForConsecutiveValues(_ predicate:(Element, Element) -> Bool) -> Bool {
return pairwise().all(pass: predicate)
}
}
"Currently what I implement is to take difference of elements and if
the diff is 1 then I say it is in sequence."
Based on your statement above, it seems your want to, for an array of integers, see if all members are consecutive.
You've already described the logic for this algorithm: you could implement it e.g. using a for ... in ... where loop, with a body which is only ever entered when the where clause identifies two subsequent elements which are not in consecutive order. E.g.:
extension Array where Element == Int {
func numbersAreConsecutive() -> Bool {
for (num, nextNum) in zip(self, dropFirst())
where (nextNum - num) != 1 { return false }
return true
}
}
var arr = [1, 2, 3, 4, 5]
print(arr.numbersAreConsecutive()) // true
arr = [1, 2, 4, 5]
print(arr.numbersAreConsecutive()) // false
arr = [1]
print(arr.numbersAreConsecutive()) // true
arr = []
print(arr.numbersAreConsecutive()) // true
arr = [2, 1]
print(arr.numbersAreConsecutive()) // false
Extending the extension to all types conforming to Integer:
extension Array where Element: Integer {
func numbersAreConsecutive() -> Bool {
for (num, nextNum) in zip(self, dropFirst())
where (nextNum - num) != 1 { return false }
return true
}
}
It will return the true if the sequence is expected otherwise it will return the false
It has two check
1.Checking whether the array is sequence(Find the array is sequence)
1.1 Sortedarray[0] + arraycount multiple with sequence (1,2,3, etc) and minus the sequence.
1.2 compare the above calculated value with last value of sorted array. if it matche we could consider The array is sequence.
2. Compare the source array and sorted array to confirm it is in order
isSeq([4,5,6,7],sequence:1) **return True**
isSeq([100,102,104,106,108],sequence:2) **return True**
isSeq([100,103,106,109,110],sequence:3) **return false**
func isSeq(_ arrayValue:[Int],sequence:Int) ->Bool{
let sortedValue = arrayValue.sorted()
if(sortedValue[0] + (sortedValue.count * sequence) - sequence == sortedValue[sortedValue.count - 1]){
if(arrayValue == sortedValue){
return true
}
}
return false;
}

Type Int does not conform to protocol sequence

I have the following code in Swift 3:
var numbers = [1,2,1]
for number in numbers.count - 1 { // error
if numbers[number] < numbers[number + 1] {
print(number)
}
}
I am checking if the value on the index [number] is always higher than the value on the index [number + 1]. I am getting an error:
Type Int does not conform to protocol sequence
Any idea?
It may be swift.
You can use this iteration.
for number in 0..<(numbers.count-1)
The error is because Int is not a Sequence. You can create a range as already suggested, which does conform to a sequence and will allow iteration using for in.
One way to make Int conform to a sequence is:
extension Int: Sequence {
public func makeIterator() -> CountableRange<Int>.Iterator {
return (0..<self).makeIterator()
}
}
Which would then allow using it as a sequence with for in.
for i in 5 {
print(i)
}
but I wouldn't recommend doing this. It's only to demonstrate the power of protocols but would probably be confusing in an actual codebase.
From you example, it looks like you are trying to compare consecutive elements of the collection. A custom iterator can do just that while keeping the code fairly readable:
public struct ConsecutiveSequence<T: IteratorProtocol>: IteratorProtocol, Sequence {
private var base: T
private var index: Int
private var previous: T.Element?
init(_ base: T) {
self.base = base
self.index = 0
}
public typealias Element = (T.Element, T.Element)
public mutating func next() -> Element? {
guard let first = previous ?? base.next(), let second = base.next() else {
return nil
}
previous = second
return (first, second)
}
}
extension Sequence {
public func makeConsecutiveIterator() -> ConsecutiveSequence<Self.Iterator> {
return ConsecutiveSequence(self.makeIterator())
}
}
which can be used as:
for (x, y) in [1,2,3,4].makeConsecutiveIterator() {
if (x < y) {
print(x)
}
}
In the above example, the iterator will go over the following pairs:
(1, 2)
(2, 3)
(3, 4)
This maybe a little late but you could have done:
for number in numbers { }
instead of:
for number in numbers.count - 1 { }
For a for loop to work a sequence (range) is needed. A sequence consists of a stating a value, an ending value and everything in between. This means that a for loop can be told to loop through a range with ether
for number in 0...numbers.count-1 { } `or` for number in numbers { }
Both example give the nesasery sequences. Where as:
for number in numbers.count - 1 { }
Only gives one value that could either be the starting or the ending value, making it impossible to work out how many time the for loop will have to run.
For more information see Apple's swift control flow documnetation
This error can also come about if you try to enumerate an array instead of the enumerated array. For example:
for (index, element) in [0, 3, 4] {
}
Should be:
for (index, element) in [0, 3, 4].enumerated() {
}
So first you need to understand what is sequence..
A type that provides sequential, iterated access to its elements.
A sequence is a list of values that you can step through one at a time. The most common way to iterate over the elements of a sequence is to use a for-in loop:
let oneTwoThree = 1...3. // Sequence
for loop actually means
For number in Sequences {}
So you need to use
for number in 0..<(numbers.count-1) {}
The error is because number is not an index, but the element of the array on each iteration. You can modify your code like this:
var numbers = [1,2,1,0,3]
for number in 0..<numbers.count - 1 {
if numbers[number] < numbers[number + 1] {
print(numbers[number])
}
}
Or there is a trick using the sort method, but that's kind of a hack (and yes, the subindexes are right, but look like inverted; you can try this directly on a Playground):
var numbers = [1,2,1,0,3]
numbers.sort {
if $0.1 < $0.0 {
print ($0.1)
}
return false
}
For me, this error occurred when I tried writing a for loop, not for an array but a single element of the array.
For example:
let array = [1,2,3,4]
let item = array[0]
for its in item
{
print(its)
}
This gives an error like: Type Int does not conform to protocol 'sequence'
So, if you get this error in for loop, please check whether you are looping an array or not.

How to Remove Every Other Element in an Array in Swift?

So say I have an array:
var stringArray = ["a","b","c","d","e","f","g","h","i","j"]
Now, how do I delete "a", "c", "e", "g", and "i" (all the even number indexes from the array)?
Thanks!
Instead of using C-style for-loops (which are set to be deprecated in an upcoming version of Swift), you could accomplish this using strides:
var result = [String]()
for i in stride(from: 1, through: stringArray.count - 1, by: 2) {
result.append(stringArray[i])
}
Or for an even more functional solution,
let result = stride(from: 1, to: stringArray.count - 1, by: 2).map { stringArray[$0] }
Traditional
var filteredArray = []
for var i = 1; i < stringArray.count; i = i + 2 {
filteredArray.append(stringArray[i])
}
Functional alternative
var result = stringArray.enumerate().filter({ index, _ in
index % 2 != 0
}).map { $0.1 }
enumerate takes a array of elements and returns an array of tuples where each tuple is an index-array pair (e.g. (.0 3, .1 "d")). We then remove the elements that are odd using the modulus operator. Finally, we convert the tuple array back to a normal array using map. HTH
There are a bunch of different ways to accomplish this, but here are a couple that I found interesting:
Using flatMap() on indices:
let result: [String] = stringArray.indices.flatMap {
if $0 % 2 != 0 { return stringArray[$0] }
else { return nil }
}
Note: result needs to be defined as a [String] otherwise the compiler doesn't know which version of flatMap() to use.
Or, if you want to modify the original array in place:
stringArray.indices.reverse().forEach {
if $0 % 2 == 0 { stringArray.removeAtIndex($0) }
}
In this case you have to call reverse() on indices first so that they're enumerated in reverse order. Otherwise by the time you get to the end of the array you'll be attempting to remove an index that doesn't exist anymore.
Swift 4.2
A function accepting generics and producing reduced result
func stripElements<T>(in array:[T]) -> [T] {
return array.enumerated().filter { (arg0) -> Bool in
let (offset, _) = arg0
return offset % 2 != 0
}.map { $0.element }
}

Resources