How to add some value to the one, two,... greater (smaller) elements of a list

How can I tell Mathematica to add a certain value ---not necessarily the same for all elements --- to the two, three, four... greater or smaller elements of a list without sorting it.

• Use Ordering[] to fetch their positions in the list, and then you can do an assignment like list[[pos]] += value. Aug 13 '17 at 17:17
• it will help if you make a MWE, giving small input and what is the output you want. Aug 13 '17 at 17:49
• Probably simplest to thread over J.-M. 's suggestion, i.e.list = {1, 4, 23, 49, 27, 18, 3}; valueDelta ={12,5,7,3}; list[[Ordering[list, -Length[valueDelta]]]] += valueDelta; to increment 4 max values; otherwise list[[Ordering[list, +Length[valueDelta]]]] += valueDelta; to increment 4 min values. See Ordering documentation here for reference. Aug 13 '17 at 21:36

b = RandomInteger[{0, 10}, {10}]


example b= {3, 4, 3, 5, 9, 2, 6, 5, 2, 2}

value = {1, 2, 3, 4};
funcMax[x_List, y_Integer, z_List] :=
ReplacePart[x,
Rule @@@ Partition[Riffle[ Ordering[x][[-y ;; -1]], z], 2]]
funcMax[b, 4, value]


output

{3, 4, 3, 1, 4, 2, 3, 2, 2, 2}

to do the same for the minimun just replace Ordering[x][[-y ;; -1]] with Ordering[x][[1 ;; y]]

ClearAll[f1, f2]
f1 = MapAt[#, #2, List /@ Ordering[##2]] &;
f2 = Module[{ord = Ordering[##2]}, ReplacePart[#2, Thread[ord -> (# /@ #2[[ord]])]]] &;


Examples:

list = {1, 4, 3, 7, 2, 7, 6, 4, 8, 2, 3, 4, 1, 9};
f1[foo, list, 3]


{foo[1], 4, 3, 7, foo[2], 7, 6, 4, 8, 2, 3, 4, foo[1], 9}

f2[foo, list, 3]


{foo[1], 4, 3, 7, foo[2], 7, 6, 4, 8, 2, 3, 4, foo[1], 9}

f1[foo, list, -3]


{1, 4, 3, 7, 2, foo[7], 6, 4, foo[8], 2, 3, 4, 1, foo[9]}

f2[foo, list, -3]


{1, 4, 3, 7, 2, foo[7], 6, 4, foo[8], 2, 3, 4, 1, foo[9]}

list = {1, 4, 3, 7, 2, 7, 6, 4, 8, 2, 3, 4, 1, 9};

n = 3;
v = 21;

list /. Thread[# -> # + v]& @ Union[list][[;; n]]


{22, 4, 24, 7, 23, 7, 6, 4, 8, 23, 24, 4, 22, 9}

Same with different values

n = 2;
v = {-100, 100};
list /. Thread[# -> # + v]& @ Union[list][[;; n]]


{-99, 4, 3, 7, 102, 7, 6, 4, 8, 102, 3, 4, -99, 9}

To change n maximum values:

list /. Thread[# -> # + v]& @ Union[list][[-n ;; -1]]


{1, 4, 3, 7, 2, 7, 6, 4, -92, 2, 3, 4, 1, 109}

This can be turned into two functions

repmin[v_, r_, n_] := v /. Thread[# -> # + r] &@Union[list][[;; n]]
repmax[v_, r_, n_] := v /. Thread[# -> # + r] &@Union[list][[-n ;; -1]]

repmax[list, {10, 11, 12}, 3]


{1, 4, 3, 17, 2, 17, 6, 4, 19, 2, 3, 4, 1, 21}

• This is a bit harder to modify for the "not necessarily the same for all elements" case. Aug 13 '17 at 18:11