2

I'm currently in the works of an AppleScript calculator that extrapolates arithmetic linear sequences (sounds fancy but it really isn't). One of the processes it must go through is finding the common difference between each item. Plugging this difference (d) into the equation for arithmetic progression, along with the term you want to know (n) will predict the nth term in any sequence.

To determine the common difference, you must first find the local difference between each pair of numbers in the sequence. Then, compare every difference; if they're all the same, the sequence is linear and the common difference is equal to the local difference. If not, the sequence is nonlinear and there is no common difference. I've figured out how to find the local differences of each number, but the latter seems to be a bigger challenge. The code I've made to determine the local differences spits out a list of numbers. My theoretical process would just compare the first item to every other, and if every comparison returns as true, then set the common difference to the same as the local difference. Below is my way of finding the local difference of a list of numbers:

set sequence to {1, 2, 3, 4, 4}
set x to 0
set dif_check to {}
repeat ((number of items of sequence) - 1) times
   set x to (x + 1)
   set selected_item to (item x of sequence)
   set local_dif to ((item (x + 1) of sequence) - selected_item)
   set dif_check to dif_check & {local_dif}
end repeat
return dif_check
--> result: {1, 1, 1, 0}
(* Since every item in the resulting list isn't equal, it would be nonlinear and the common difference would just be n/a. *)

How would I determine if every item in a list is the same? I've tried numerous times, including this script I experimented with, but I realized it didn't get me anywhere closer to the resolution:

set dif_check to {1, 1, 1, 0}
set first_term to (first item of dif_check)
set x to 1
set common_dif_check to {}
repeat ((number of items of dif_check) - 1) times
   set x to (x + 1)
   (item x of dif_check) = first_term
   set common_dif_check to common_dif_check & {result}
end repeat
return common_dif_check
--> result: {true, true, false}
(* This takes the first item of the list and compares it with every item after, returning a true or false and adding the result to another list. I thought this would have solved it, but instead just turns out as the same situation as before. *)

To reiterate, how would I determine if every item in a list is the same? Any help with this would be greatly appreciated. Thanks in advance.

2

I’m not sure if this will help but this following code will remove duplicate items from a list and create a new list from the results. It will then count the items of the new list and if the items in that new list is greater than 1 … that means all of the items of the original list were not the same

property difCheck : {1, 1, 1, 0}
property allItemsAreTheSame : missing value

set itemCount to count of removeDuplicates(difCheck)

if itemCount is greater than 1 then
    set allItemsAreTheSame to false
else
    set allItemsAreTheSame to true
end if

on removeDuplicates(theList)
    script k
        property |List| : theList
        property tmpList : {}
    end script
    repeat with itemRef in k's |List|
        set theItem to itemRef's contents
        if k's tmpList does not contain theItem then ¬
            set k's tmpList's end to theItem
    end repeat
    return k's tmpList
end removeDuplicates
  • 1
    OK, I can’t believe I am about to say this, but excellent job. This is night and day compared to previous stuff. I see you have finally come around to using looping through a list without having to use a counter, which is perfect in this situation. I’m going to offer two small ideas that are by no means needed, but maybe you’ll facepalm: the first thing is the odd return value of the handler that reverses the list. Then I see two lines previously, it’s prepended new items rather than appending them. If you change beginning to end, you can get rid of the reverse. Cont’d... – CJK Nov 9 '20 at 9:53
  • 1
    ...Cont’d The second thing is no better or worse than what’s currently there, and actually many people prefer your explicit approach to setting the value for allItemsAreTheSame by handling each case separately, which makes it easier to see immediately what’s happening in what situation. But, unlike my comments, I like brevity in scripts where I can get it, and setting a boolean whose value is derived from another boolean necessarily makes them the same (well, homeomorphic). So it’s always possible to do: set allItemsAreTheSame to itemCount < 2. But, a +1 from me! – CJK Nov 9 '20 at 10:02
  • 1
    @CJK Thanks for the kudos on my coding. In response to ”looping through a list without having to use a counter”… early on I did not have a great understanding of “referencing items” and realized that using the counter in my repeat loops I did not get nearly as many errors. I guess I just got lazy and stuck to what I knew always worked for me. You are correct. The whole prepending and reverse thing… FACE PALM! The set allItemsAreTheSame to itemCount < 2 had never occurred to me. Another item added to my arsenal thank you very much – wch1zpink Nov 9 '20 at 20:18
0

Only a couple of modifications required.

set dif_check to {1, 1, 1, 0}
set first_term to (first item of dif_check)
set x to 1
set terms_are_same to true
repeat ((number of items of dif_check) - 1) times
    set x to (x + 1)
    if ((item x of dif_check) ≠ first_term) then
        set terms_are_same to false
    end if
end repeat
return terms_are_same

The trick is to use a variable that is set to true unless one of the comparisons fails.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .