Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
84 views
in Technique[技术] by (71.8m points)

javascript - Create a heap that prioritizes based on occurance of competitor field

This is a mockup variable that i am using to test:

[
    { competitor: 1 },
    { competitor: 1 },
    { competitor: 1 },
    { competitor: 1 },
    { competitor: 2 },
    { competitor: 3 },
    { competitor: 4 },
    { competitor: 4 },
    { competitor: 4 },
    { competitor: 5 },
    { competitor: 6 },
    { competitor: 6 },
    { competitor: 7 },
    { competitor: 7 },
    { competitor: 7 },
    { competitor: 8 },
    { competitor: 9 },
    { competitor: 10 },
    { competitor: 11 },
    { competitor: 12 },
  ]

This is the code for grouping repeated items:

const splitRepeated = (array) => {
  let obj = array.reduce((res, curr) => {
    if (res[curr.competitor]) res[curr.competitor].push(curr);
    else Object.assign(res, { [curr.competitor]: [curr] });

    return res;
  }, {});
  return obj;
};

This is the result:

{
  '1': [
    { competitor: 1 },
    { competitor: 1 },
    { competitor: 1 },
    { competitor: 1 }
  ],
  '2': [ { competitor: 2 } ],
  '3': [ { competitor: 3 } ],
  '4': [ { competitor: 4 }, { competitor: 4 }, { competitor: 4 } ],
  '5': [ { competitor: 5 } ],
  '6': [ { competitor: 6 }, { competitor: 6 } ],
  '7': [ { competitor: 7 }, { competitor: 7 }, { competitor: 7 } ],
  '8': [ { competitor: 8 } ],
  '9': [ { competitor: 9 } ],
  '10': [ { competitor: 10 } ],
  '11': [ { competitor: 11 } ],
  '12': [ { competitor: 12 } ]
}

Now i need to distribute the repeated elements of this array evenly;

evenly example:

[{ competitor: 1 },{ competitor: 2 },{ competitor: 3 },{ competitor: 1 },{ competitor: 4 },{ competitor: 5 },{ competitor: 1 }]

this is my best try at all:

const spreadOrder3 = (array) => {
  let obj = splitRepeated(array);
  let objEntities = Object.entries(obj);
  console.log(obj);
  let newArray = objEntities.map((x) => x[1][0]).flat();
  let oldIndex = newArray.length;
  for (let e = 0; e < oldIndex; e++) {
    let each = Math.floor(oldIndex / objEntities[e][1].length);

    let counter = 0;
    for (let i = 0; i < objEntities[e][1].length; i++) {
      console.log(objEntities[e][1][i]);
      console.log((counter + 1) * each);
      newArray.splice((counter + 1) * each, 0, objEntities[e][1][i]);
      // newArray[(counter + 1) * each] = objEntities[e][1][i];
      counter++;
    }
  }
  return newArray;
};

The results aren't good, i need help, i can never get repeated elements together thank you

Expected result:

Array length unique elements: 12

competitor: 1 // has 4 repeated then: 12/4 = 3, then insert competitor 1 every 3 elements

competitor: 4 // has 3 repeated then: 12/3 = 4, then insert competitor 4 every 4 elements

competitor: 6 // has 2 repeated then: 12/2 = 6, then insert competitor 6 every 6 elements

competitor: 7 // has 3 repeated then: 12/3 = 4, then insert competitor 7 every 4 elements

Result needs to be like this:

[{ competitor: 1 },{ competitor: 2},{ competitor: 3 },{ competitor: 1 }, { competitor: 4 },{ competitor: 5 },{ competitor: 1 }]
question from:https://stackoverflow.com/questions/65893092/create-a-heap-that-prioritizes-based-on-occurance-of-competitor-field

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You could group the values and sort the grouped values by length of the same value.

Take an array of indices for the result array and disperse the values of the same group with the same distance

Math.floor((indices.length - 1) / (a.length - 1))

into the result array by using the indices array. Remove used indices from indices array and proceed until no more values are to ditribute.

0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19  indices at start

1  1  1  1  2  3  4  4  4  5  6  6  7  7  7  8  9 10 11 12  values
1                 1                 1                 1     d = 6
   4                       4                       4
      7                       7                          7
         6                                      6
            2  3     5  8        9    10 11 12              solitary values

const
    data = [1, 1, 1, 1, 2, 3, 4, 4, 4, 5, 6, 6, 7, 7, 7, 8, 9, 10, 11, 12],
    indices = [...data.keys()],
    groups = data.reduce((r, v) => ((r[v] ??= []).push(v), r), {}),
    result = Object
        .values(groups)
        .sort((a, b) => b.length - a.length)
        .reduce((r, a) => {
            const d = a.length === 1 ? 1 : Math.floor((indices.length - 1) / (a.length - 1));
            a.forEach((v, i) => r[indices.splice(i * d - i, 1)[0]] = v);
            return r;
        }, []);

console.log(...result);

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...