"Ambiguous Reference to Member Map" When Attempting to Append/Replace Array Element

Ambiguous reference to member map when attempting to append/replace array element

Unfortunately, swift is not perfect and can not infer types at all times, this is why you are getting the ambiguous reference. Try userDicts.map {val -> [String:AnyObject] in and swap out $0 for val This will explicitly tell the map that the values coming in are [String:AnyObject], and should be able to return said type

Ambiguous reference to member map from concrete type

The error message is misleading. The real problem is that the map()
method applied to a dictionary does not return a new dictionary but an array, in your case [(String, String)],
See for example What's the cleanest way of applying map() to a dictionary in Swift? for a discussion of that topic.

Another problem is that NSString is not converted to String
implicitly, i.e. NSString(data: data, ...) should be replaced by
String(data: data, ...).

Using the extension method

extension Dictionary {
init(_ pairs: [Element]) {
self.init()
for (k, v) in pairs {
self[k] = v
}
}
}

from the referenced thread you can return a new dictionary with

func convert(v: AnyObject) -> [String: String] {
let dict = v as! [CBUUID: NSData]
return Dictionary(dict.map { (uuid, data) in
(uuid.UUIDString, String(data: data, encoding: NSUTF8StringEncoding) ?? "")
})
}

Alternatively, change the return type to [(String, String)]:

func convert(v: AnyObject) -> [(String, String)] {
return (v as! [CBUUID: NSData]).map { (uuid, data) in
(uuid.UUIDString, String(data: data, encoding: NSUTF8StringEncoding) ?? "")
}
}

Swift 3: sum value with group by of an array of objects

First of all Data is reserved in Swift 3, the example uses a struct named Item.

struct Item {
let value : Float
let name : String
}

Create the data array with your given values

let dataArray = [Item(value:10.5, name:"apple"), 
Item(value:20.0, name:"lemon"),
Item(value:15.2, name:"apple"),
Item(value:45, name:"")]

and an array for the result:

var resultArray = [Item]()

Now filter all names which are not empty and make a Set - each name occurs one once in the set:

let allKeys = Set<String>(dataArray.filter({!$0.name.isEmpty}).map{$0.name})

Iterate thru the keys, filter all items in dataArray with the same name, sum up the values and create a new Item with the total value:

for key in allKeys {
let sum = dataArray.filter({$0.name == key}).map({$0.value}).reduce(0, +)
resultArray.append(Item(value:sum, name:key))
}

Finally sort the result array by value desscending:

resultArray.sorted(by: {$0.value < $1.value})

---

Edit:

Introduced in Swift 4 there is a more efficient API to group arrays by a predicate, Dictionary(grouping:by:

var grouped = Dictionary(grouping: dataArray, by:{$0.name})
grouped.removeValue(forKey: "") // remove the items with the empty name

resultArray = grouped.keys.map { (key) -> Item in
let value = grouped[key]!
return Item(value: value.map{$0.value}.reduce(0.0, +), name: key)
}.sorted{$0.value < $1.value}

print(resultArray)

Generic Extension to Array Not Working

Give this a shot

extension Array where Element: Equatable {
func replaced (each valueToReplace: Element, with newValue: Element) -> [Element] {
var newArray = [Element]()
newArray.reserveCapacity(self.count)

for element in self {
let newElement = (element == valueToReplace) ? newValue : element
newArray.append(newElement)
}

return newArray
}

mutating func replace(each valueToReplace: Element, with newValue: Element) {
for (i, element) in self.enumerated() {
if element == valueToReplace { self[i] = newValue }
}
}
}

var j = [1,2,3,4,3,6,3,8,9]
var newArray = j.replaced(each: 3, with: 0)

It would be better to remove the redundancy by just making replaced delegate to replace:

extension Array where Element: Equatable {
func replaced(each valueToReplace: Element, with newValue: Element) -> [Element] {
var copy = self
copy.replace(each: valueToReplace, with: newValue)
return copy
}

mutating func replace(each valueToReplace: Element, with newValue: Element) {
for (i, element) in self.enumerated() {
if element == valueToReplace { self[i] = newValue }
}
}
}

React replace item in array

I had bit hard time understanding the question but is this what you want https://codesandbox.io/s/vj7vxw198y ? It still would need some work to allow adding same item multiple times if you want that.

Python-pandas: the truth value of a series is ambiguous

Let's reduce it to a simpler example. By doing for instance the following comparison:

3 == pd.Series([3,2,4,1])

0 True
1 False
2 False
3 False
dtype: bool

The result you get is a Series of booleans, equal in size to the pd.Series in the right hand side of the expression. So really what's happening here is that the integer is being broadcast across the series, and then they are compared. So when you do:

if 3 == pd.Series([3,2,4,1]):
pass

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

You get an error. The problem here is that you are comparing a pd.Series with a value, so you'll have multiple True and multiple False values, as in the case above. This of course is ambiguous, since the condition is neither True or False.

So you need to further aggregate the result so that a single boolean value results from the operation. For that you'll have to use either any or all depending on whether you want at least one (any) or all values to satisfy the condition.

(3 == pd.Series([3,2,4,1])).all()
# False

or

(3 == pd.Series([3,2,4,1])).any()
# True

Truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all()

The or and and python statements require truth-values. For pandas, these are considered ambiguous so you should use "bitwise" | (or) or & (and) operations:

df = df[(df['col'] < -0.25) | (df['col'] > 0.25)]

These are overloaded for these kinds of data structures to yield the element-wise or or and.


Just to add some more explanation to this statement:

The exception is thrown when you want to get the bool of a pandas.Series:

>>> import pandas as pd
>>> x = pd.Series([1])
>>> bool(x)
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

What you hit was a place where the operator implicitly converted the operands to bool (you used or but it also happens for and, if and while):

>>> x or x
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
>>> x and x
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
>>> if x:
... print('fun')
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
>>> while x:
... print('fun')
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

Besides these 4 statements there are several python functions that hide some bool calls (like any, all, filter, ...) these are normally not problematic with pandas.Series but for completeness I wanted to mention these.


In your case, the exception isn't really helpful, because it doesn't mention the right alternatives. For and and or, if you want element-wise comparisons, you can use:

  • numpy.logical_or:

      >>> import numpy as np
    >>> np.logical_or(x, y)

    or simply the | operator:

      >>> x | y
  • numpy.logical_and:

      >>> np.logical_and(x, y)

    or simply the & operator:

      >>> x & y

If you're using the operators, then be sure to set your parentheses correctly because of operator precedence.

There are several logical numpy functions which should work on pandas.Series.


The alternatives mentioned in the Exception are more suited if you encountered it when doing if or while. I'll shortly explain each of these:

  • If you want to check if your Series is empty:

      >>> x = pd.Series([])
    >>> x.empty
    True
    >>> x = pd.Series([1])
    >>> x.empty
    False

    Python normally interprets the length of containers (like list, tuple, ...) as truth-value if it has no explicit boolean interpretation. So if you want the python-like check, you could do: if x.size or if not x.empty instead of if x.

  • If your Series contains one and only one boolean value:

      >>> x = pd.Series([100])
    >>> (x > 50).bool()
    True
    >>> (x < 50).bool()
    False
  • If you want to check the first and only item of your Series (like .bool() but works even for not boolean contents):

      >>> x = pd.Series([100])
    >>> x.item()
    100
  • If you want to check if all or any item is not-zero, not-empty or not-False:

      >>> x = pd.Series([0, 1, 2])
    >>> x.all() # because one element is zero
    False
    >>> x.any() # because one (or more) elements are non-zero
    True

Kotlin's List missing add, remove, Map missing put, etc?

Unlike many languages, Kotlin distinguishes between mutable and immutable collections (lists, sets, maps, etc). Precise control over exactly when collections can be edited is useful for eliminating bugs, and for designing good APIs.

https://kotlinlang.org/docs/reference/collections.html

You'll need to use a MutableList list.

class TempClass {
var myList: MutableList<Int> = mutableListOf<Int>()
fun doSomething() {
// myList = ArrayList<Int>() // initializer is redundant
myList.add(10)
myList.remove(10)
}
}

MutableList<Int> = arrayListOf() should also work.



Related Topics



Leave a reply



Submit