In Google Sheets - I need to sum a set of numbers, where the initial cell contains delimiters and non numerics:
3; 6; 1; 3; None; 1; 1
I first replace all spaces and non numerics:
=REGEXREPLACE(AG24,"\D+",",")
Which gives: 3,6,1,3,1,1
Since =SUM(3,6,1,3,1,1) correctly provides 15, I figured I'd try passing in the REGEXREPLACE result into SUM() and magically have it compute, but doing so yields 0:
=SUM(REGEXREPLACE(AG24,"\D+",",")) = 0
I kind of expected that...
I've also tried SUMPRODUCT, which also yields 0:
=SUMPRODUCT(ARRAYFORMULA(REGEXREPLACE(AG24,"\D+",","))) = 0
Question: so how can I sum the list of string integers?
You can try the below formula which will directly convert the string to array ad then make a sum of it.
=Sum(SPLIT(AG24,";"))
Hope it helps!
Please try:
=sum(split(REGEXREPLACE(AG24,"\D+",","),","))
=SUMPRODUCT(SPLIT(AG24, ";"))
=SUMPRODUCT(SPLIT(REGEXREPLACE(AG24,"\D+"," ")," "))
will work as well...
Related
everyone. I'm trying to do an iterative equation solver, where I put an equation then each iteration substitutes the X for a value then solves it. I'm having a hard time since the iterated function is considered a string. Any help is appreciated, thank you. The equation needs to be dynamic and be solved via iterations.
I tried calling the =substitute cell and end up having invalid data, since it reads as string.
try:
=BYROW(A9:A24, LAMBDA(ii, INDEX(QUERY(,
"select "®EXREPLACE(REGEXREPLACE(REGEXREPLACE(B2, "\^\d+", REPT("*x",
REGEXEXTRACT(B2, "\^(\d+)")-1)), "\(", "*("), "x", ii&"")), 2)))
logic:
caret ^ is not supported by QUERY so we first transform ^2 into an alternative. we know x^2 is equal to x*x so we extract that 2 and subtract 1 and REPT *x one time
next, we need to add multiplication as ()() needs to become ()*() same as 50x to 50*x
then we substitute x with value and evaluate the string with QUERY's SQL ## logic:
basically, we transform your:
-50(x)-1/2(-9.81)(x^2)+35
into:
-50*(0)-1/2*(-9.81)*(0*0)+35
-50*(1)-1/2*(-9.81)*(1*1)+35
-50*(2)-1/2*(-9.81)*(2*2)+35
etc.
UPDATE:
x^n where n is <1 are unachievable with REPT method and QUERY does not support roots so we can use a script to convert a text string into the formula
poor script example:
function onEdit(){
var sheet = SpreadsheetApp.getActiveSheet();
var source1= sheet.getRange('F7');
var source2= sheet.getRange('F8');
var formula1 = source1.getValue();
var formula2 = source2.getValue();
var target1 = sheet.getRange('B7');
var target2 = sheet.getRange('B8');
target1.setFormula(formula1);
target2.setFormula(formula2);
}
where F7 contains:
=BYROW(A7:A23, LAMBDA(i, "POW("&INDEX(QUERY(, "select "®EXREPLACE(
SUBSTITUTE(REGEXEXTRACT(B3, "(.+)\^"), ")(", ")*("), "x", i&"")), 2)&","&
REGEXEXTRACT(B3, "\^\((.+)\)")&")"))
What formula should I use in Google Sheets to get a sum of multiple cells, where every cell has an independent condition determining wether it should be included in the sum or not. Something like this:
result = 0 + (IF(condition1, A1)) + (IF(condition2, B1)) + (IF(condition3, C1))
Depending on your conditions, you can use something similar to this:
=SUM(IF(A1<>0,A1,0),IF(B1<10,B1,0),IF(C1<10,C1,0),D1)
Therefore, as a general example, you can simply make use of the SUM and the IF functions:
=SUM(IF(CONDITION1,A1,0),IF(CONDITION2,B1,0),IF(CONDITION3,C1,0)...)
the elements of the SUM function are separated by a comma;
the IF returns the first value if the condition is met and the second one if the condition is not met.
Reference
SUM function;
IF function.
Turns out it works the way I posted in Original Question:
result = 0 + (IF(condition1, A1)) + (IF(condition2, B1)) + (IF(condition3, C1))
BUT you need to use a different parameter separator if comma (,) is used as a decimal point separator in your language. For Polish I had to use semicolon (;)
result = 0 + (IF(condition1; A1)) + (IF(condition2; B1)) + (IF(condition3; C1))
I need to do a bitwise "and" in a cypher query. It seems that cypher does not support bitwise operations. Any suggestions for alternatives?
This is what I want to detect ...
For example 268 is (2^8 + 2^3 + 2^2) and as you can see 2^3 = 8 is a part of my original number. So if I use bitwise AND it will be (100001100) & (1000) = 1000 so this way I can detect if 8 is a part of 268 or not.
How can I do this without bitwise support? any suggestions? I need to do this in cypher.
Another way to perform this type of test using cypher would be to convert your decimal values to collections of the decimals that represent the bits that are set.
// convert the binary number to a collection of decimal parts
// create an index the size of the number to convert
// create a collection of decimals that correspond to the bit locations
with '100001100' as number
, [1,2,4,8,16,32,64,128,256,512,1024,2048,4096] as decimals
with number
, range(length(number)-1,0,-1) as index
, decimals[0..length(number)] as decimals
// map the bits to decimal equivalents
unwind index as i
with number, i, (split(number,''))[i] as binary_placeholder, decimals[-i-1] as decimal_placeholder
// multiply the decimal value by the bits that are set
with collect(decimal_placeholder * toInt(binary_placeholder)) as decimal_placeholders
// filter out the zero values from the collection
with filter(d in decimal_placeholders where d > 0) as decimal_placeholders
return decimal_placeholders
Here is a sample of what this returns.
Then when you want to test whether the number is in the decimal, you can just test the actual decimal for presence in the collection.
with [4, 8, 256] as decimal_placeholders
, 8 as decimal_to_test
return
case
when decimal_to_test in decimal_placeholders then
toString(decimal_to_test) + ' value bit is set'
else
toString(decimal_to_test) + ' value bit is NOT set'
end as bit_set_test
Alternatively, if one had APOC available they could use apoc.bitwise.op which is a wrapper around the java bitwise operations.
RETURN apoc.bitwise.op(268, "&",8 ) AS `268_AND_8`
Which yields the following result
If you absolutely have to do the operation in cypher probably a better solution would be to implement something like #evan's SO solution Alternative to bitwise operation using cypher.
You could start by converting your data using cypher that looks something like this...
// convert binary to a product of prime numbers
// start with the number to conver an a collection of primes
with '100001100' as number
, [2,3,5,7,13,17,19,23,29,31,37] as primes
// create an index based on the size of the binary number to convert
// take a slice of the prime array that is the size of the number to convert
with number
, range(length(number)-1,0,-1) as index
, primes[0..length(number)] as primes, decimals[0..length(number)] as decimals
// iterate over the index and match the prime number to the bits in the number to convert
unwind index as i
with (split(number,''))[i] as binary_place_holder, primes[-i-1] as prime_place_holder, decimals[-i-1] as decimal_place_holder
// collect the primes that are set by multiplying by the set bits
with collect(toInt(binary_place_holder) * prime_place_holder) as prime_placeholders
// filter out the zero bits
with filter(p in prime_placeholders where p > 0) as prime_placeholders
// return a product of primes of the set bits
return prime_placeholders, reduce(pp = 1, p in prime_placeholders | pp * p) as prime_product
Sample of the output of the above query. The query could be adapted to update attributes with the prime product.
Here is a screen cap of how the conversion breaks down
Then when you want to use it you could use the modulus of the prime number in the location of the bit you want to test.
// test if the fourth bit is set in the decimal 268
// 268 is the equivalent of a prime product of 1015
// a modulus 7 == 0 will indicate the bit is set
with 1015 as prime_product
, [2,3,5,7,13,17,19,23,29,31,37] as primes
, 4 as bit_to_test
with bit_to_test
, prime_product
, primes[bit_to_test-1] as prime
, prime_product % primes[bit_to_test-1] as mod_remains
with
case when mod_remains = 0 then
'bit ' + toString(bit_to_test) + ' set'
else
'bit ' + toString(bit_to_test) + ' NOT set'
end as bit_set
return bit_set
It almost certainly defeats the purpose of choosing a bitwise operation in the first place but if you absolutely needed to AND the two binary numbers in cypher you could do something like this with collections.
with split('100001100', '') as bin_term_1
, split('000001000', '') as bin_term_2
, toString(1) as one
with bin_term_1, bin_term_2, one, range(0,size(bin_term_1)-1,1) as index
unwind index as i
with i, bin_term_1, bin_term_2, one,
case
when (bin_term_1[i] = one) and (bin_term_2[i] = one) then
1
else
0
end as r
return collect(r) as AND
Thanks Dave. I tried your solutions and they all worked. They were a good hint for me to find another approach. This is how I solved it. I used String comparison.
with '100001100' as number , '100000000' as sub_number
with number,sub_number,range(length (number)-1,length (number)-length(sub_number),-1) as tail,length (number)-length(sub_number) as difference
unwind tail as i
with i,sub_number,number, i - length (number) + length (sub_number) as sub_number_position
with sub_number_position, (split(number,''))[i-1] as bit_mask , (split(sub_number,''))[sub_number_position] as sub_bit
with collect(toInt(bit_mask) * toInt(sub_bit)) as result
return result
Obviously the number and sub_number can have different values.
I have a formula calculating a number :
F = SUMIFS(Besoins!$D$2:$D$999;Besoins!$C$2:$C$999;C$1;Besoins!$B$2:$B$999;$B5)
What I try to do then is to print either the result :
if F > 0, or "-" if F = 0
So I try with the IF function :
=IF(F=0;"-";?)
I don't know what to use to print the correct result when it is false. Anyone know how I could do it?
Unfortunately, you cannot set a variable in a spreadsheet formula; that is, you cannot actually set the name F to your SUM expression there. You can either write:
=IF(SUM(Besoins!$D$2:$D$999;Besoins!$C$2:$C$999;C$1;Besoins!$B$2:$B$999;$B5)=0,"-",SUM(Besoins!$D$2:$D$999;Besoins!$C$2:$C$999;C$1;Besoins!$B$2:$B$999;$B5))
Or you could store SUM(Besoins!$D$2:$D$999;Besoins!$C$2:$C$999;C$1;Besoins!$B$2:$B$999;$B5) in one cell (for the sake of argument, cell A1) and in another cell, write:
=IF(A1=0,"-",A1)
Easy question here, probably, but searching did not find a similar question.
The # operator finds the length of a string, among other things, great. But with Lua being dynamically typed, thus no conversion operators, how does one type a number as a string in order to determine its length?
For example suppose I want to print the factorials from 1 to 9 in a formatted table.
i,F = 1,1
while i<10 do
print(i.."! == "..string.rep("0",10-#F)..F)
i=i+1
F=F*i
end
error: attempt to get length of global 'F' (a number value)
why not use tostring(F) to convert F to a string?
Alternatively,
length = math.floor(math.log10(number)+1)
Careful though, this will only work where n > 0!
There are probably a dozen ways to do this. The easy way is to use tostring as Dan mentions. You could also concatenate an empty string, e.g. F_str=""..F to get F_str as a string representation. But since you are trying to output a formatted string, use the string.format method to do all the hard work for you:
i,F = 1,1
while i<10 do
print(string.format("%01d! == %010d", i, F))
i=i+1
F=F*i
end
Isn't while tostring(F).len < 10 do useful?