简体   繁体   English

JavaScript:根据排列顺序对数组进行排序?

[英]JavaScript: Sort array based on a permutation order?

I have a list of N elements with an array of three colors like this:我有一个包含三个 colors 数组的 N 元素列表,如下所示:

[
  { id: 1, colors: ['Red', 'Blue', 'White'] },
  { id: 2, colors: ['Red', 'Blue', 'Blue'] },
  { id: 3, colors: ['Red', 'Red', 'White'] },
  { id: 4, colors: ['Red', 'Red', 'Red'] }
]

And I would like to sort them based on this priority order, for example:我想根据这个优先顺序对它们进行排序,例如:

[Red,Red,Red]
[Red,Red,X]
[Red,X,Red]
[Red,X,X]
[X,Red,Red]
[X,Red,X]
[X,X,Red]

Where the 'X' indicates any other color that is not the one I indicate, in this example is 'Red'.在“X”表示任何其他颜色的地方不是我指定的颜色,在这个例子中是“红色”。

So an expected output, for this example would be:因此,对于此示例,预期的 output 将是:

[
  { id: 1, colors: ['Red', 'Red', 'Red'] },
  { id: 2, colors: ['Red', 'Red', 'White'] },
  { id: 3, colors: ['Red', 'Blue', 'White'] },
  { id: 4, colors: ['Red', 'Blue', 'Blue'] }
]

Any idea on how to approach this?关于如何解决这个问题的任何想法?

I tried finding the duplicates and sorting the parent array based on the colors, but I need to take into consideration the priority order.我尝试根据 colors 查找重复项并对父数组进行排序,但我需要考虑优先级顺序。

elements.sort((a, b) => {
  const colorDupsA = findDuplicates(a.colors);
  const colorDupsB = findDuplicates(b.colors);
  return colorDupsB.length - colorDupsA.length;
});

Or, using an index array srt you can do it in the following way:或者,使用索引数组srt您可以通过以下方式执行此操作:

 const arr=[ {id: 1,colors: ['Red', 'Blue', 'White']}, {id: 1,colors: ['Red', 'Blue', 'Blue']}, {id: 1,colors: ['Red', 'Red', 'White']}, {id: 1,colors: ['Red', 'Red', 'Red']}]; const srt=arr.map((e,i)=>[i,e.colors.map(c=>c=="Red"?"1":"0").join("")]) console.log(srt.sort((a,b)=>b[1]-a[1]).map(([i])=>arr[i]));

You can even reduce it to a one-liner:您甚至可以将其简化为单行:

arr.map((e,i)=>[i,e.colors.map(c=>c=="Red"?"1":"0").join("")])
   .sort((a,b)=>b[1]-a[1]).map(([i])=>arr[i])

So you need to loop over the arrays and figure out if the one is red and the other.因此,您需要遍历 arrays 并确定一个是红色的,另一个是红色的。 If they both or or both are not, then you move to the next and check.如果他们两者或两者都不是,那么你移动到下一个并检查。

 const data = [ { colors: ['Blue', 'Blue', 'Red'] }, { colors: ['Blue', 'Red', 'White'] }, { colors: ['Blue', 'Blue', 'White'] }, { colors: ['Red', 'Blue', 'White'] }, { colors: ['Red', 'Blue', 'Blue'] }, { colors: ['Red', 'Red', 'White'] }, { colors: ['Red', 'Red', 'Red'] } ]; data.sort((a,b) => { const ac = a.colors; const bc = b.colors for (let i=0; i<ac.length; i++){ const check = (ac[i] === bc[i]) || (ac[i];== 'Red' && bc[i];== 'Red')? if (check) continue: return ac[i] === 'Red'; -1; 1; } return 0. }); console.log(data);

If you have to do sorting based on the other colors, generating a "weighted value" for the array would be a way to go如果您必须根据其他 colors 进行排序,则为数组生成“加权值”将是 go 的一种方法

 const data = [ { colors: ['Blue', 'Blue', 'Red'] }, { colors: ['Blue', 'Red', 'White'] }, { colors: ['Blue', 'Blue', 'White'] }, { colors: ['Red', 'Blue', 'White'] }, { colors: ['Red', 'Blue', 'Blue'] }, { colors: ['Red', 'Red', 'White'] }, { colors: ['Red', 'Red', 'Red'] } ]; const values = { Red: 3, Blue: 2, White: 1, }; const weight = arr => +arr.map(c => values[c] || 0).reverse().join(""); data.sort((a, b) => weight(b.colors) - weight(a.colors)); console.log(data);

Here is a possible solution:这是一个可能的解决方案:

  1. Create a private function getColorScore to calculate the score of a colors array according to the occurrences of your color and its indices in it.创建一个私有 function getColorScore以根据您的颜色及其在其中的索引的出现来计算colors数组的分数。 This can be done using .reduce这可以使用.reduce来完成
  2. Sort the array of objects using this function, where the object with the greater score for its colors list, would be first.使用此 function 对对象数组进行排序,其中colors列表中score较高的 object 将是第一个。 This is done using .sort这是使用.sort完成的

 const arr = [ { id: 1, colors: ['Red', 'Blue', 'White'] }, { id: 1, colors: ['Red', 'Blue', 'Blue'] }, { id: 1, colors: ['Red', 'Red', 'White'] }, { id: 1, colors: ['Red', 'Red', 'Red'] } ]; const getColorScore = (colors, color) => colors.reduce((acc,item,index) => { acc += item===color? colors.length-index: 0; return acc; }, 0); const sortArrayByColor = (arr,color) => arr.sort((a,b) => getColorScore(b.colors,color)-getColorScore(a.colors,color)) console.log( sortArrayByColor(arr,'Red') );

In the sort method, Calculate the value for each object based on permutation order and compare values.sort方法中,根据排列顺序计算每个 object 的value并比较值。

 const data = [ { colors: ["Blue", "Blue", "Red"] }, { colors: ["Blue", "Red", "White"] }, { colors: ["Blue", "Blue", "White"] }, { colors: ["Red", "Blue", "White"] }, { colors: ["Red", "Blue", "Blue"] }, { colors: ["Red", "Red", "White"] }, { colors: ["Red", "Red", "Red"] }, ]; const getValue = (obj) => obj.colors.reduce((acc, cur) => +(cur === "Red") + acc * 10, 0); data.sort((a, b) => getValue(b) - getValue(a)); console.log(data);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM