i want to create a function that compares 2 arrays and returns indexes of items found. if for examples my arrays are:
var distances:Array = new Array (0,275,217,385,275,0,251);
var selectedDist:Array = new Array (217,275,251);
i would like it to return 2,4,6
Try the following:
var indices:Array = [];
for each(var distance:int in selectedDist) {
var index:int = distances.indexOf(distance);
if (index >= 0) {
indices.push(index);
}
}
return indices;
Supposing you would always compare selectedDist array to distances array, I would do that :
protected function compareArrays(arr1:Array, arr2:Array):Array
{
var matches:Array = new Array();
for(var x:int=0; x < arr2.length; x++) {
/*
* indexOf returns -1 id the element is not found in the array
* http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/Array.html#indexOf()
* but you have to grab the lastIndexOf 275, as requested...
*/
if (arr1.indexOf(arr2[x] > -1))
matches.push(arr1.lastIndexOf(arr2[x]));
}
return matches;
}
Related
var a=[0,0,0,0]
var b=[0,0,0,0]
for i in 0..<4{
var g=i%2==0 ? a:b
g[i]+=1
//10 more lines of code about array g
}
I want to implement something like whenever i is an even number increment the i position of A by 1, and if i is odd increment the i position of B by 1.
The expecting result is A=[1,0,1,0] and B is [0,1,0,1]
Here modifying the array g will not affect the original array because of deep copy. Are there any ways to modify array a and b without using if...else statement?
You have to modify a value type directly, a possible solution is
var a = [0,0,0,0]
var b = [0,0,0,0]
for i in 0..<4 {
i.isMultiple(of: 2) ? (a[i] += 1) : (b[i] += 1)
}
Another solution is to use a class (reference type) wrapper
class Wrapper {
var array = [0,0,0,0]
}
let a = Wrapper()
let b = Wrapper()
for i in 0..<4 {
let g = i.isMultiple(of: 2) ? a : b
g.array[i] += 1
}
print(a.array)
print(b.array)
var a=[0,0,0,0]
var b=[0,0,0,0]
for i in 0..<4{
i%2==0 ? (a[i] += 1) : (b[i] += 1)
}
print(a)
print(b)
Result A=[1,0,1,0] B = [0,1,0,1]
You could use a function with an inout parameter:
func modify(g: inout [Int], index: Int) {
g[index] += 1
// 10 more lines of code about array g
}
var a = [0,0,0,0]
var b = [0,0,0,0]
for i in 0..<4 {
if i.isMultiple(of: 2) {
modify(g: &a, index: i)
} else {
modify(g: &b, index: i)
}
}
print(a)
print(b)
You could also put the arrays into a class (reference type) and use that reference to access the array instead of trying to reference the arrays (value types) directly.
See inout documentation here
Some info on value vs reference types
You are not "thinking value type", yet. For those, copy, modify, and reassign.
var array: [Int] { .init(repeating: 0, count: 4) }
let (a, b) = array.indices.reduce( into: (array, array) ) { arrays, index in
let indexIsEven = index.isMultiple(of: 2)
// Copy
var array = indexIsEven ? arrays.0 : arrays.1
// Modify
array[index] = 1
// Reassign
indexIsEven
? (arrays.0 = array)
: (arrays.1 = array)
}
my array looks like that:
var arr = [a,b,c,d,d,e,a,b,c,f,g,h,h,h,e,a];
How to create object from array?
array value is become key of object and count duplicate value is become value of object
I want to get following object
{
"a" : 3
"b" : 1
"c" : 2
"d" : 2
}
Is this what you're trying to achieve?
https://jsfiddle.net/yf184qob/
var arr = ['a','b','c','d','d','e','a','b','c','f','g','h','h','h','e','a'];
var obj = {};
for(var a in arr){
var temp = arr[a];
if(typeof obj[temp] == "undefined"){
obj[temp] = 0;
}
obj[temp]++;
}
console.log(obj);
var arr =['a','b','c','d','d','e','a','b','c','f','g','h','h','h','e','a'];
var cv ={};
for(var i=0;i<arr.length;i++)
{
if (!(arr[i] in cv))
{
cv[arr[i]] =1
}else
{
cv[arr[i]]=cv[arr[i]]+1;
}
}
One can filter an array like this in swift:
var numbers = Array(1...1000000)
numbers = numbers.filter( { return $0 % 2 == 0 } )
Is it possible to filter and avoid the copy operation, that occurs when the filtering is done, e.g mutating the original array.
In a similar way to this pseudocode:
numbers.MutablefilterOperation({ return $0 % 2 == 0})
In C++ the equvivalent to what is going on in Swift above would be:
std::vector<int> originalNumbers(1000000);
std::vector<int> newNumbers;
std::copy_if (originalNumbers.begin(), originalNumbers.end(), std::back_inserter(newNumbers), [](int i) { return i % 2 == 0 } );
What I would like to achieve for performance reasons:
std::vector<int> originalNumbers(1000000);
auto pos = std::remove_if(originalNumbers.begin(), originalNumbers.end(), [](int x) { return x % 2 == 0; });
originalNumbers.erase(pos, originalNumbers.end());
This implementation should do the filtering without having to make a temporary copy of the entire array in the process (unless a copy of it is referenced by another variable, see "Copy on Write")
extension Array {
mutating func filterInPlace(isIncluded: (Element) throws -> Bool) rethrows {
var writeIndex = self.startIndex
for readIndex in self.indices {
let element = self[readIndex]
let include = try isIncluded(element)
if include {
if writeIndex != readIndex {
self[writeIndex] = element
}
writeIndex = self.index(after: writeIndex)
}
}
self.removeLast(self.distance(from: writeIndex, to: self.endIndex))
}
}
// example:
var arr = [6,2,6,5,2,5,6,2,2,1,6,7,3]
arr.filterInPlace { $0 % 2 == 1 }
print(arr) // [5, 5, 1, 7, 3]
When I try to add an item to my array it gives me and EXC BAD INSTRUCTION error and it says
fatal error: Array index out of range
That is the code:
var tabelle : [[Actions]] = [[]]
func doSomething() {
var results = self.fetch()
var oldProjektName: String = results[0].projektName
var count: Int = 0
for item in results {
if oldProjektName == item.projektName {
tabelle[count].append(item)
} else {
count++
tabelle[count].append(item)
}
oldProjektName = item.projektName
}
}
As long as count = 0 it does not give me an error but when count = 1 then the app crashes.
You have an array with one element: var tabelle : [[Actions]] = [[]]
That is why tabelle[0] is working.
You need to append another array to tabelle before you can use tabelle[1]
Try
var tabelle = [[Actions]](())
I'm struggling with something that shouldn't be too difficult but I can't figure it out I have a number of Arrays with different values and I want to find the common values all of the Arrays have, see example below:
var arrayOne:Array = ["1","2","3"];
var arrayTwo:Array = ["1","2","7"];
var arrayThree:Array = ["1","2","9","12"];
_resultArray = ["1","2"];
Any help is appreciated.
You can do something like:
///Returns common values between to arrays
function getCommonValues(array1:Array, array2:Array):Array
{
var len1:int = array1.length;
var len2:int = array2.length;
var toReturn:Array = new Array();
for(var i:int = 0; i < len1; i++){
for(var n:int = 0; n < len2; n++){
if(array1[i] == array2[n]){
toReturn.push(array1[i]);
}
}
}
return toReturn;
}
Then do something like:
var arrayOneAndTwo:Array = getCommonValues(arrayOne,arrayTwo);
var _resultArray:Array = getCommonValues(arrayOneAndTwo,arrayThree);
Optionally you can modify the function to include all three arrays in the comparison, which would be more efficient.
Edit
If you want to process an unknown amount of arrays you can add:
///Returns common values between X number of sub arrays
function getCommonValuesFromSubArrays(papaArray:Array):Array
{
if(papaArray.length < 2){ return papaArray; }
var toReturn:Array = papaArray[0];
for(var a:int = 1; a < papaArray.length; a++){
toReturn = getCommonValues(toReturn, papaArray[a]);
}
return toReturn;
}
Then something like:
var arr1:Array = ["one","two","three","four","five"];
var arr2:Array = ["one","two","five","six"];
var arr3:Array = ["one","two","three","four","five"];
var arr4:Array = ["one","two","three","four","five"];
var bigOlArray:Array = [arr1,arr2,arr3,arr4];
var _results:Array = getCommonValuesFromSubArrays(bigOlArray);
I would use a function to concatenate all arrays, sort by numerical value, and collect all items that are available exactly as many times as the number of arrays that were passed in as parameters:
var arrayOne : Array = [ "1", "2", "3" ];
var arrayTwo : Array = [ "1", "2", "7" ];
var arrayThree : Array = [ "1", "2", "9", "12" ];
// you can pass in any number of Arrays
trace ( searchArraysForCommonItems ( arrayOne, arrayTwo, arrayThree ) ); // returns ["1", "2"]
function searchArraysForCommonItems ( ...args : * ) : Array
{
var searchArray : Array = [];
for each ( var arr:Array in args)
searchArray = searchArray.concat ( arr );
var resultArray : Array = [];
var last : String;
var times : int = 0;
for each ( var str : String in searchArray.sort ( Array.NUMERIC ))
if (last == str) times++;
else
{
if (times == args.length) resultArray.push ( last );
last = str;
times = 1;
}
return resultArray;
}
Of course, you can (and should) use Vector.<String> instead of Array wherever possible to improve performance, but always remember that Array.sort() is a native function and very fast...
I would use the Array.filter() Function to achieve this:
var _resultArray:Array = arrayOne.filter(
function(item:String, index:int, arr:Array):Boolean
{
return (arrayTwo.indexOf(item) != -1 && arrayThree.indexOf(item));
}
);
This will loop over arrayOne and return an array with the values that both appear also in arrayTwo and arrayThree.
Edit: And here is a function that will take any number of arrays and return the common values:
function getCommonValues(arrayOne:Array, ... arrays:Array):Array
{
var _resultArray:Array = arrayOne.filter(
function(item:String, index:int, arr:Array):Boolean
{
return arrays.every(
function (a:Array, index2:int, arr2:Array):Boolean
{
return a.indexOf(item) != -1;
}
);
}
);
return _resultArray;
}
Usage:
resultArray = getCommonValues(arrayOne, arrayTwo, arrayThree, arrayFour);
The function has another nested closure inside the first one, so might be a bit hard to understand, but I tested it, it works.