How to write a mango filter on the size of an array? - couchdb

I would like to find documents with a mango query by specifying the minimal and maximal size of an array property. Given a document with an array property customers. I'd like to be able to find all documents with the number of customers between 10 and 20.
Something like
mango_query = {
"doc.customers": {"$size": {"gte": 10}},
"doc.customers": {"$size": {"lte": 20}}
}
The response to a request like that is
Bad argument for operator $size: {[{<<36,108,116,101>>,10}]}')
So how should I write a mango filter on the size of an array?

Checking the code here, only integer argument is supported for $size operator. So it can't be combined with other operators. It supports only $size exact matches.
norm_ops({[{<<"$size">>, Arg}]}) when is_integer(Arg), Arg >= 0 ->
{[{<<"$size">>, Arg}]};
norm_ops({[{<<"$size">>, Arg}]}) ->
?MANGO_ERROR({bad_arg, '$size', Arg});
And when matching
match({[{<<"$size">>, Arg}]}, Values, _Cmp) when is_list(Values) ->
length(Values) == Arg;
match({[{<<"$size">>, _}]}, _Value, _Cmp) ->
false;
length(Values) == Arg Only exact match is supported

Related

Nim: Find index of element in seq based on predicate

If I have a sequence of values, how would I find the index of an element based on a predicate function? For example, if I had the following seq:
let values = #["pie", "cake", "ice cream"]
How would I find the index of the first element with four characters? I know of find, but it seems to only find index by equality, and does not allow passing a predicate. I could implement this myself but it feels as if it should be be in the standard library if find is.
A simple solution would be to use map from sequtils to map the predicate over the input sequence, and then to use find to get the index of the first true value in the result. This returns -1 when no element of the sequence satisfies the predicate:
import sequtils
proc isLen4(s: string): bool =
len(s) == 4
echo map(#["pie", "cake", "ice cream"], isLen4).find(true) #--> 1
This works, but is bad for large sequences since map processes the entire sequence. Thus even when the first element satisfies the predicate the entire sequence is processed. It would be better to just write a findIf procedure that returns the current index when the predicate is satisfied instead of continuing to process the rest of the input:
proc findIf[T](s: seq[T], pred: proc(x: T): bool): int =
result = -1 # return -1 if no items satisfy the predicate
for i, x in s:
if pred(x):
result = i
break
echo #["pie", "cake", "ice cream"].findIf(isLen4) #--> 1

Sort list of string based on length

I have a list of strings
List("cbda","xyz","jlki","badce")
I want to sort the strings in such a way that the odd length strings are sorted in descending order and even length strings are sorted in ascending order
List("abcd","zyx","ijkl","edcba")
Now I have implemented this by iterating over each elements separately, then finding their length and sorting them accordingly. Finally I store them in separate list. I was hoping to know if there is any other efficient way to do this in Scala, or any shorter way to do this (like some sort of list comprehensions we have in Python) ?
You can do it with sortWith and map:
list.map(s => {if(s.length % 2 == 0) s.sortWith(_ < _) else s.sortWith(_ > _)})
I'm not sure what you refer to in Python, so details could help if the examples below don't match your expectations
A first one, make you go through the list twice:
List("cbda","xyz","jlki","badce").map(_.sorted).map {
case even if even.length % 2 == 0 => even
case odd => odd.reverse
}
Or makes you go through elements with even length twice:
List("cbda","xyz","jlki","badce").map {
case even if even.length % 2 == 0 => even.sorted
case odd => odd.sorted.reverse
}

sort list of maps in grovvy

Hi I have a list of maps in groovy like
def v=[[val1:'FP'],[val1:'LP'],[val1:'MP'],[val1:'MP'],[val1:'LP'],[val1:'FP']]
I wanted to sort based on the following order FP,MP,LP
I tried doing
v.sort{x,y->
x.val1 <=> y.val1
}
which prints [[val1:FP], [val1:FP], [val1:LP], [val1:LP], [val1:MP], [val1:MP]] which is sorted alphabetically, but I need it to be sorted in the following format
FP,MP,LP
An alternative: Whenever I am dealing with a fixed, ordered list of strings I immediately think of using enums instead:
enum PValue { FP, MP, LP }
Now we have an ordered set of constants that readily converts to and from string values. So sorting looks as simple as this:
v.sort { x, y -> PValue[x.val1] <=> PValue[y.val1] }
EDIT: Or even simpler:
v.sort { PValue[it.val1] }
As has been said int the comments, you need to define a preferred order, and then sort based on that... so with your list of maps:
def v=[[val1:'FP'],[val1:'LP'],[val1:'MP'],[val1:'MP'],[val1:'LP'],[val1:'FP']]
And a preferred order of results:
def preferredOrder = ['FP', 'MP', 'LP']
You can then sort based on the values index into this preferred order:
v.sort(false) { preferredOrder.indexOf(it.val1) }
Or, if you want unknown elements (ie: [val1:'ZP']) to go at the end of the sorted list, then you an do:
v.sort(false) { preferredOrder.indexOf(it.val1) + 1 ?: it.val1 }
So if they are not found (index -1) then they are compared on their String name
This question is similar to this one btw, which has more options in the answer

string 'w32' == 0 evaluates to true in php. huh?

So I was getting a notice in my php while creating a google product feed.
The notice was
"The following php notice has occurred 4989 times on the _ site today:
PHP Notice: Undefined index: 0 in /xxx/Status.php on line 583"
This was the code in that class
public function inStockLocally($productcode)
{
if($this->_status[$productcode]['status'] == self::IN_STOCK) {
return $this->_status[$productcode]['in_stock_local'];
}
return false;
}
The function was getting a $productcode = 0, but the productcode was infact 'w32', so the key didn't exist.
up the stack where the function was being called I put this in, in order to break on the troublesome product.
if ($productcode == 0) {
$test = 'breakhere';
}
Using netbeans and firebug, it broke on the line when $productcode = 'w32'
So my question is why does 'w32' == 0 evaluate to true?
It is also evaluating to true with other similar structure codes like 'h94'.
Any help would be appreciated as no one in the department can figure out why this is happening.
I guess I didn't put enough info in the q. Two things going on.
1. 'w32' converted to a number = 0 for some reason. 2. [0] is being inserted as my key in the array when the productcode has the structure 'x##';
I'm a little new here, so pardon if this isn't the answer you were expecting, but PHP does a lot of automatic type conversion. So any string that doesn't start with a numeric character (0..9, +, -, etc) will evaluate to zero.
"If you compare a number with a string or the comparison involves numerical strings, then each string is converted to a number and the comparison performed numerically. "
http://php.net/manual/en/language.operators.comparison.php
Additionally, I suppose you have an indexed array, although you expect it to be an associative array:
The array() function is used to create an array.
In PHP, there are three types of arrays:
Indexed arrays - Arrays with numeric index
Associative arrays - Arrays with named keys
Multidimensional arrays - Arrays containing one or more arrays
Syntax
Syntax for indexed arrays:
array(value1,value2,value3,etc.);
Syntax for associative arrays:
array(key=>value,key=>value,key=>value,etc.);

How can I sort a list of strings in Dart?

I see in the API docs there is a sort() method on List, but I'm not clear what it needs for a parameter. The current need is for a very simple straight up alpha comparison.
1. A Quick Solution
Thanks for the question! You can sort a list of Strings like this:
main() {
final List<String> fruits = <String>['bananas', 'apples', 'oranges'];
fruits.sort();
print(fruits);
}
The above code prints:
[apples, bananas, oranges]
2. Slightly more advanced usage
Notice that sort() does not return a value. It sorts the list without creating a new list. If you want to sort and print in the same line, you can use method cascades:
print(fruits..sort());
For more control, you can define your own comparison logic. Here is an example of sorting the fruits based on price.
main() {
final List<String> fruits = <String>['bananas', 'apples', 'oranges'];
fruits.sort((a, b) => getPrice(a).compareTo(getPrice(b)));
print(fruits);
}
Let's see what's going on here.
A List has a sort method, which has one optional parameter: a Comparator. A Comparator is a typedef or function alias. In this case, it's an alias for a function that looks like:
int Comparator(T a, T b)
From the docs:
A Comparator function represents such a total ordering by returning a negative integer if a is smaller than b, zero if a is equal to b, and a positive integer if a is greater than b.
3. How to do it with a list of custom objects
Additionally, if you create a list composed of custom objects, you could add the Comparable<T> as a mixin or as inheritance (extends) and then override the compareTo method, in order to recreate the standard behavior of sort() for your list of custom objects. For more info, do check out this other, related StackOverflow answer.
Here is the one line code to achieve it.
fruits.sort((String a, String b)=>a.compareTo(b)); //fruits is of type List<String>
For Sorting Simple List of Integers or Strings:
var list = [5 , -5 ,1];
list.sort(); //-5 , 1 , 5
For Reversing the list order:
list.reversed;
For Sorting List of Objects or Map by field of it:
List<Map<String, dynamic>> list= [
{"name": "Shoes", "price": 100},
{"name": "Pants", "price": 50},
];
// from low to high according to price
list.sort((a, b) => a["price"].compareTo(b["price"]));
// from high to low according to price
list.sort((a, b) => b["price"].compareTo(a["price"]));
To add just one point to Seth's detailed answer, in general, in
(a, b) => foo(a, b)
passed into sort, the function foo should answer an integer result as follows:
if a < b, result should be < 0,
if a = b, result should be = 0, and
if a > b, result should be > 0.
For the above law of trichotomy to hold, both a and b must be Comparables.
use compareAsciiUpperCase instead of compareTo, as it supports strings and automatically ignores case sensitive:
import "package:collection/collection.dart";
data.sort((a, b) {
return compareAsciiUpperCase(a.name, b.name);
});
After today, you should just be able to do list.sort() .
The sort method's argument is now optional, and it defaults to a function that calls compareTo on the elements themselves. Since String is Comparable, it should Just Work now.
How I have solved this problem.
List<Product> _dataSavingListProducts = [];
List<Product> _dataSavingListFavoritesProducts = [];
void _orderDataSavingLists() {
_dataSavingListProducts.toList().reversed;
_dataSavingListFavoritesProducts.toList().reversed;
}

Resources