I encountered one weird application of the "FIND" function which I don't quite know how it work. Could someone enlighten me?
This formula results in "19"
=MEDIAN(FIND({1,2,3,4,5,6,7,8,9},"2 notch lower0123456789"))
This formula results in "23"
=MAX(FIND({1,2,3,4,5,6,7,8,9},"2 notch lower0123456789"))
This formula results in "1"
=MIN(FIND({1,2,3,4,5,6,7,8,9},"2 notch lower0123456789"))
This formula results in "15"
=FIND({1,2,3,4,5,6,7,8,9},"2 notch lower0123456789")
The results obviously tie with the number of characters. But how exactly does this syxtax of FIND work?
Thanks,
First, because of the matrix argument, FIND() runs in a loop, for the values 1, 2, ...9 (as specified inside the {}).
FIND returns then the position of the first match inside the string "2 notch lower0123456789", for each number (as a character), so the 1 is found at position 15, the 2 at position 1, the 3 at position 17, the 4 at position 18, etc, until the 9 is found at position 23.
The result of this matrix operation will be the list {15,1,17,18,19,20,21,22,23}.
Now apply the functions to that:
MEDIAN({15,1,17,18,19,20,21,22,23}) -> the middle value is 19!
MAX({15,1,17,18,19,20,21,22,23}) -> obviously 23
MIN({15,1,17,18,19,20,21,22,23}) -> obviously 1
{15,1,17,18,19,20,21,22,23} -> if you don't apply anything to it, a matrix gets reduced to the first element, so 15.
Definitely weird usage, I agree.
Related
Suppose I have a column of wind directions ("N","S","W",E"). Each cell only contains 1 letter. If I am to find the most common wind directions,=CHAR(MODE(CODE(range))) will do the job
But if I handle wind directions like "SW","NE", the above function would not work. I know that =INDEX(range, MODE(MATCH(range, range, 0 ))) will work.
Just curious, somewhat similar to the first function, is there a way to substitue strings with numbers of choice only when passing in the column into MODE()function, so that it will return a number for me to MATCH() and INDEX() to get the result?
Clarify: Say that I have the following data
And I would like to substitue "N" with 0, "NE" with 45, "SW" with 225 and so on. So that MODE() will be applicable. And if needed, I can then use functions like INDEX(MATCH()) to return the actual letter representation of the wind direction.
=SWITCH(MODE(SWITCH(A:A,"N",0,"NE",45,"E",90,"SE",135,"S",180,"SW",225,"W",270,"NW",315,"")),0,"N",45,"NE",90,"E",135,"SE",180,"S",225,"SW",270,"W",315,"NW","")
Or similar:
=CHOOSE(1+MODE(SWITCH(A:A,"N",0,"NE",45,"E",90,"SE",135,"S",180,"SW",225,"W",270,"NW",315,""))/45,"N","NE","E","SE","S","SW","W","NW")
This first translates the strings to values, then translates the MODE result back to it's string.
I'm parsing strings in excel, and I need to return everything through the last number. For example:
Input: A00XX
Output: A00
In my case, I know the last number will be between index 3 and 5, so I'm brute-forcing it with:
=LEFT([#Point],
IF(SUM((MID([#Point],5,1)={"0","1","2","3","4","5","6","7","8","9"})+0),5,
IF(SUM((MID([#Point],4,1)={"0","1","2","3","4","5","6","7","8","9"})+0),4,
IF(SUM((MID([#Point],3,1)={"0","1","2","3","4","5","6","7","8","9"})+0),3,
))))
Unfortunately, I've run into some edge cases where the numbers extended beyond index 5. Is there a generic way to find the last number in a string using excel formulas?
Note:
I've tried =MAX(SEARCH(... but it returns the index of the first number, not the last.
As a starting point: if we know the position of the last number, we can use LEFT to get the string to that point. Suppose that the position is 5:
=LEFT(A1, 5)
But, we don't know the position of the last number. Now, what if the only valid number was 0, and it only appeared once: then we could use FIND to locate the position of the number:
=LEFT(A1, FIND(0, A1))
But, we have more than one valid number. Suppose that we had all the numbers from 0 through 9, but each number could only appear once — then we could use MAX on a FIND array, to tell us which of the numbers is the last one:
=LEFT(A1, MAX(FIND({0,1,2,3,4,5,6,7,8,9}, A1)))
Unfortunately, FIND will throw a #VALUE! error any number doesn't appear, which will then make MAX return the same error. So, we need to fix that with IFERROR:
=LEFT(A1, MAX(IFERROR(FIND({0,1,2,3,4,5,6,7,8,9}, A1), 0)))
However, numbers can appear more than once. As such, we need a method to find the last occurrence of a value in a string (since FIND and SEARCH will, by default, return the first occurrence).
The SUBSTITUTE function has 3 mandatory arguments — Initial String, Value to be Replaced, Value to Replace with — and one Optional argument — the occurrence to replace. Normally, this is omitted, so that all occurrences are replaced. But, if we know how many times a character appears in a string, then we can replace just the last instance with a special/uncommon sub-string to search for.
To count how many times a character appears in a String, just start with the length of the String, then subtract the length when you SUBSTITUTE all copies of that character for Nothing:
=LEN(A1) - LEN(SUBSTITUTE(A1, 0, ""))
This means we can now replace the last occurrence of the character with, for example, ">¦<", and then FIND that:
=FIND(">¦<", SUBSTITUTE(A1, 0, ">¦<", LEN(A1) - LEN(SUBSTITUTE(A1, 0, ""))))
Of course, we want to do this for all the numbers from 0 to 9, and take the MAX value (remembering our IFERROR), so we need to put the Array of values back in:
=MAX(IFERROR(FIND(">¦<", SUBSTITUTE(A1, {0,1,2,3,4,5,6,7,8,9}, ">¦<", LEN(A1) - LEN(SUBSTITUTE(A1, {0,1,2,3,4,5,6,7,8,9}, "")))), 0))
Then, we plug that all back into our initial LEFT function:
=LEFT(A1, MAX(IFERROR(FIND(">¦<", SUBSTITUTE(A1, {0,1,2,3,4,5,6,7,8,9}, ">¦<", LEN(A1) - LEN(SUBSTITUTE(A1, {0,1,2,3,4,5,6,7,8,9}, "")))), 0)))
An alternative, assuming that the length of the string in question will never be more than 9 characters (which seems a safe assumption based on your description):
=LEFT(A1,MATCH(0,0+ISERR(0+MID(A1,{1;2;3;4;5;6;7;8;9},1))))
This, depending on your version of Excel, may or may not require committing with CTRL+SHIFT+ENTER.
Note also that the separator within the array constant {1;2;3;4;5;6;7;8;9} is the semicolon, which, for English-language versions of Excel, represents the row-separator. This may require amending if you are using a non-English-language version.
Of course, we can replace this static constant with a dynamic construction. However, since we are already making the assumption that 9 is an upper limit on the number of characters for the string in question, this would not seem to be necessary.
If you have the newest version of Excel, you can try something like:
=LEFT(D1,
LET(x, SEQUENCE(LEN(D1)),
MAX(IF(ISNUMBER(NUMBERVALUE(MID(D1, SEQUENCE(LEN(D1)), 1))), x))))
For example:
i have a lot of address data in (mostly) this format:
Karl-Reimann-Ring 13, 99087 Erfurt
Markttwiete 2, 23611 Bad Schwartau
Hüxstraße 55, 23552 Lübeck
Bunsenstraße 1c, 24145 Kiel
and my goal is to extract the zip code.
I copied a formula from a website, which i dont really understand:
=VERWEIS(9^9;1*TEIL(E2861&"#";SPALTE(2860:2860);6))
VERWEIS = LOOKUP,
TEIL = MID,
SPALTE = COLUMN
This formula seems to work 99% of the time, also for the ones above, but for some i get weird results.
Kurt-Schumacher-Straße 56, 55124 Mainz --> 44340
Kleine Früchtstraße 6, 55130 Mainz --> 44346
Bahnstraße 1, 55128 Mainz --> 44344
All with 'Mainz' are wrong and start with 44xxx
But when i increase the last argument from 6 to 7 it seems to work.
Do somebody know, how i can impove this formula to get always the correct zip code?
The problem is that the formula will return the last "number" which is constructed of 6 character strings starting at every character in the string.
The last substring that can be interpreted numerically (in the 55424 Mainz address) is actually 24 Mai. German Excel will parse that into 24 Mai 2021 which, as a number, will be 44340.
One modification you can make to your formula, to prevent that from happening, would be to add a comma after the zipcode. eg:
=LOOKUP(9^9;1*MID(SUBSTITUTE(A1;" ";",") & "#";COLUMN(2860:2860);6))
Another option would be to use FILTERXML where you can separate by spaces, and then return the last numeric node:
=FILTERXML("<t><s>" &SUBSTITUTE(A1;" ";"</s><s>") & "</s></t>";"//s[number(.) = number(.)][last()]")
So I have a cell with the following information, for example "Score 8/10" and I need a formula that translates to "if the value is between 0 and 4, return "Bad", if the value is between 5 and 7, return "Medium", if the value is between 8 and 10, return "Good".
I tried a If with a mid to extract the "8" from the "Score 8/10", but couldn't manage to get the rest of the result.
Please try:
=CHOOSE(MATCH(1*TRIM(MID(A1,FIND("/",A1)-2,2)),{0,5,8}),"Bad","Medium","Good")
Here is my answer, although I think #pnut's is preferable.
=IF(MID(A3,(FIND(" ",A3,1)+1),FIND("/",A3,(FIND(" ",A3,1)+1))-(FIND(" ",A3,1)+1))+0<5,"Bad", IF(MID(A3,(FIND(" ",A3,1)+1),FIND("/",A3,(FIND(" ",A3,1)+1))-(FIND(" ",A3,1)+1))+0>7, "Good","Medium"))
This gets the characters between the first space character and the first "/" character, converts them to a number and then compares than number to select an appropriate value.
I've been working on this programming challenge: http://www.codeabbey.com/index/task_view/summing-up
Which basically states:
Input data has two values A and B in the single line.
Output should have the sum A+B printed into it.
Additionally after the stop the program should have values A, B, A+B in the cells 0, 1 and 2 respectively.
So for example input would look like this:
9 26
Now, I think I be misunderstanding either the problem or the solution because I believe the solution is supposed to be 9 26 35 where 9, 26, and 35 are all in their own cells.
My solution returns 9 26 35 and I believe in the correct cells (0,1, and 2 respectfully) but I am getting the answer wrong. Can anyone please look at the problem and my code and tell me where I am going wrong?
Code:
;:>;:><[-<+>]<:
I tried plugging this into a couple of online brainfuck interpreters. There is one here:
http://copy.sh/brainfuck/
and another here:
http://esoteric.sange.fi/brainfuck/impl/interp/i.html
In both cases, I needed to change your character set slightly --> : becomes . and ; becomes ,
The output from both was
9 Y
Notice that 35 - 9 = 24, and Y is the 24th letter of the alphabet. I think you are outputting the number "35" and having it interpretted as a letter.
I would try changing the program so that your output is literally single digits of the answer -- ie, output a 3, then output a 5, instead of outputting a numerical "35" (but leave the numerical value in cell 2 at the end). In other words, your text output should be a formatted version of the values in memory, rather than just outputting the numerical values directly.
It sounds like the output should only have A+B printed, not A, B, and A+B, as you're doing with :.
And your result seems like it'll have A+B in cell 0, and 0 in cell 1 (essentially the same as the example code).
>< is just cancelling itself out.