I have an array, with even number of elements:
var peoples = [
["1", "Adam", "Jones"],
["2", "Michael", "Jordan"],
["3", "Frank", "Forman"],
["4", "John", "Bryant"],
["5", "James", "Johnson"],
["6", "Vincent", "Carter"],
["7", "George", "Williams"],
["8", "Brandon", "Clarkson"]
];
and I’m trying to merge arrays in pairs by following pattern:
["1", "Adam", "Jones", "2", "Michael", "Jordan"]
["3", "Frank", "Forman","4", "John", "Bryant"]
etc.
I have a problem with following code:
for (var i = 0; i < peoples.length / 2; i++) {
array1[i].push(array2[i].join(","))
}
which is generating that result:
["1","Adam","Jones","2,Michael,Jordan"]
and it should be:
["1","Adam","Jones","2","Michael","Jordan"]
Here is my jsfiddle https://jsfiddle.net/danny3b/k5hza694/
I've already done it by myself. I was looking for concat() method.
for (var i = 0; i < peoples.length / 2; i++) {
array1[i] = array1[i].concat(array2[i])
}
https://jsfiddle.net/danny3b/rfju9949/
What join does is concatenating all of the strings in the array. Instead of that, you should insert all of the elements in there.
Related
I would like to get the row and column index in ForEach loop of a 2D array in swiftUI.
let array = [
["1", "2", "3"],
["4", "5", "6"],
["7", "8", "9"]
]
ForEach(array, id: .self) { row in
ForEach(row, id: \.self) { element in
// How to get the index i and j for row and column of a 2D array in swiftUI ???
}
}
Since you have an array of [String] you must have 2 ForEach:
ForEach(Array(row.enumerated()), id:\.self) { i, array in
ForEach(Array(array.enumerated()), id: \.self) { j, element in
//do something
}
}
try something like this, ...to get the index i and j for row and column of a 2D array...:
struct ContentView: View {
let array = [["1", "2", "3"],["4", "5", "6"],["7", "8", "9"]]
var body: some View {
ForEach(array.indices, id: \.self) { i in
ForEach(array[i].indices, id: \.self) { j in
Text(array[i][j])
}
}
}
}
var myArray: [[String]] =
[
["1", "picture1.png", "John", "Smith"],
["2", "picture2.png", "Mike", "Rutherford"],
]
How to sort myArray on first item ? second item ? ascending ? descending ?
Many Thanks
I would suggest you create a struct or class to package this related data together:
struct Person {
let id: Int
let picture: String // This should probably be a URL, NSImage or UIImage
let firstName: String
let lastName: String
}
And then define your instances with the correct types (e.g. the id is an Int, not a String representation of an Int.
let people = [
Person(
id: 1,
picture: "picture1.png",
firstName: "John",
lastName: "Smith"
),
Person(
id: 2,
picture: "picture2.png",
firstName: "Mike",
lastName: "Rutherford"
),
]
From there, you can sort it any which way you please:
people.sorted{ $0.id < $1.id }
people.sorted{ $0.id > $1.id }
people.sorted{ $0.picture < $1.picture }
people.sorted{ $0.picture > $1.picture }
people.sorted{ $0.firstName < $1.firstName }
people.sorted{ $0.firstName > $1.firstName }
people.sorted{ $0.lastName < $1.lastName }
people.sorted{ $0.lastName > $1.lastName }
Notice, that index ranged is not checked, what could lead to a fatal error at runtime. Check Alexanders comment! :)
var myArray: [[String]] =
[
["1", "picture1.png", "John", "Smith"],
["2", "picture2.png", "Mike", "Rutherford"],
]
func sort<T: Comparable>(ArrayOfArrays: [[T]], sortingIndex: Int, sortFunc: (T, T) -> Bool)) -> [[T]] {
return ArrayOfArrays.sorted {sortFunc($0[sortingIndex], $1[sortingIndex])}
}
}
print(sort(ArrayOfArrays: myArray, sortingIndex: 0, sortFunc: <))
//[["1", "picture1.png", "John", "Smith"], ["2", "picture2.png", "Mike", "Rutherford"]]
print(sort(ArrayOfArrays: myArray, sortingIndex: 0, sortFunc: >))
//[["2", "picture2.png", "Mike", "Rutherford"], ["1", "picture1.png", "John", "Smith"]]
Swift's Array has a built-in sort function. Just call it.
myArray[0].sort { $0.compare($1, options: .numeric) == .orderedAscending }
myArray[1].sort { $0.compare($1, options: .numeric) == .orderedDescending }
To sort the arrays using numeric string comparison (e.g. where "2" < "10") of the item at a particular index:
let index = 1 // sort by second entry
myArray.sort { $0[index].compare($1[index], options: .numeric) == .orderedAscending }
If you don't need numeric comparisons (e.g. where "10" < "2"):
myArray.sort { $0[index] < $1[index] }
As others point out, though, you really should be using arrays of custom struct or class rather than representing your objects as mere array of strings.
I try to sort a String Array with numbers but i dont get the right order.
print(alleTouren) // ["1", "3", "2", "5", "15", "4"]
alleTouren = alleTouren.sorted(by: {$0 < $1})
print(alleTouren) // ["1", "15", "2", "3", "4", "5"]
I also tried alleTouren.sort(by:<) and alleTouren.sort() but i always get back the 15 too early. What i am doing wrong?
Since all strings can be converted to Int add the conversion to the closure.
var alleTouren = ["1", "3", "2", "5", "15", "4"]
alleTouren = alleTouren.sorted(by: { Int($0)! < Int($1)! })
Alternatively use the compare function of String with numeric option which is probably more efficient.
alleTouren = alleTouren.sorted(by: { $0.compare($1, options:.numeric) == .orderedAscending} )
The problem is that you seem to be saying you want to sort them as though they are numbers, but they are strings, so "1", "15", "2"... is correct. You could try converting $0 and $1 to integers and comparing these.
I'm not a Swift expert, but this seems to work:
alleTouren = alleTouren.sorted{let s0 = Int($0)
let s1 = Int($1)
return s0! < s1!}
If I have an array: array = ["ruby", "code", "library"]. How can I move matched /^library$/ elements to the beginning. So array will look like this: array = ["library", "ruby", "code"]
it could be done in a number of ways. This is one
array = ["ruby", "code", "library"]
array.partition { |element| element.match /^library$/ }.flatten
Just out of curiosity:
[:select, :reject].map do |m|
["ruby", "code", "library"].public_send(m, &(/^library/.method(:=~)))
end.reduce :|
def move_to_front(arr, pattern)
mi = matching_indices(arr, pattern)
return arr unless mi
a = arr.dup
mi.reverse_each.with_object([]) { |i,b| b.unshift(a.delete_at(i)) }.concat(a)
end
def matching_indices(arr, pattern)
arr.each_index.select do |i|
case pattern
when Regexp then arr[i] =~ pattern
when Proc then pattern[arr[i]]
else (arr[i] == pattern)
end
end
end
move_to_front ["ruby", "code", "library"], /\Alibrary\z/
#=> ["library", "ruby", "code"]
move_to_front ["ruby", "library", "code", "library"], "library"
#=> ["library", "library", "ruby", "code"]
move_to_front ["ruby", "libraries", "code", "library"], /librar(?:ies|y)/
#=> ["libraries", "library", "ruby", "code"]
move_to_front ["ruby", "libraries", "code", "library"], /\Alibrar/
#=> ["libraries", "library", "ruby", "code"]
move_to_front ["ruby", "libraries", "code", "library"],
->(str) { str =~ /librar(?:ies|y)/ }
#=> ["libraries", "library", "ruby", "code"]
move_to_front ("1".."9").to_a, /[13579]/
#=> ["1", "3", "5", "7", "9", "2", "4", "6", "8"]
move_to_front ("1".."9").to_a, ->(n) { n.to_i.odd? }
#=> ["1", "3", "5", "7", "9", "2", "4", "6", "8"]
move_to_front ("1".."9").to_a, ->(n) { false }
#=> ["1", "2", "3", "4", "5", "6", "7", "8", "9"]
move_to_front ("1".."9").to_a, ->(n) { true }
#=> ["1", "2", "3", "4", "5", "6", "7", "8", "9"]
Note:
matching_indices ["ruby", "libraries", "code", "library"], /librar(?:ies|y)/
#=> [1, 3]
The method move_to_front preserves the order of those elements that are moved and those that are not moved.
Three for one cent.
array.inject([]){|a,e| e[/^library/] ? a.unshift(e) : a<<e}
and
array & ["library"] | array
In case array contains the search element multiple times it becomes
array.find_all{ |e| e[/^library/] } + array.reject{ |e| e[/^library/] }
If you hate to use the array variable twice it can also like this
[array].map{|a| a & ["library"] | a}.flatten
The last one: using grep
array.grep(/library/) + array.grep( /^(?!library)/)
I am trying to combine two two arrays to make a full deck of cards that looks like so:
[{card: "A", suit: "d"}, {card: "A", suit: "c"}, {card: "A", suit: "s"}, {card: "A", suit: "h"}, {card: "2", suit: "d"}.....]
.... this is what I have so far:
function newDeck(ranks, suits){
var ranks = [ "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"]
var suits = ["d", "c", "s", "h"]
var deck= []
for (i = 0; i < suits.length; i++) {
for (j = 0; j < ranks.length; j++) {
this.deck[ranks.length*i+j] = new Card(ranks[j], suits[i]);
}
} console.log(newDeck)
}
Using Array.forEach you can do the following:
var ranks = [ "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"];
var suits = ["d", "c", "s", "h"];
var deck= [];
suits.forEach(function(suit){
ranks.forEach(function(rank){
deck.push(new Card(rank, suit));
})
});
EDIT: and in case you haven't written the Card method yet:
function Card(rank, suit){
this.card = rank;
this.suit = suit;
}
If you combine the two arrays you will have an array:
["A","2","3","4","5","6","7","8","9","10","J","Q","K","d","c","s","h"]
which does not represent a full deck of card, whereas using an embedded for loop to print out card as you are now will so I don't think you just want to append one array to the other. Can you provide more context on what you want to do with the array?
However, to answer your question: if you want to append two arrays you can use:
var appendedArray = ranks.concat(suits);
which will result in the aforementioned array above
pertaining to your updated question: you are called "new Card(ranks[j], suits[i]);" have you made a Card constructor so that this is valid? if so, the code should be correct if the constructor matches how you are using it. Posting the code for the constructor would be helpful along with an update of what issue you are facing