简体   繁体   English

映射对象数组并从未知键中挑选值

[英]Mapping over array of objects and picking out values from unknown keys

Tallying which color has a greater value in each array element for data.在数据的每个数组元素中统计哪种颜色具有更大的值。 Then push the higher valued color into an empty object, and/or increment that color by 1. Lastly sort the totals object highest to lowest in terms of the totals property values and return highest valued color然后将较高值的颜色推入空的 object,和/或将该颜色递增 1。最后根据总计属性值对总计 object 从最高到最低进行排序,并返回最高值的颜色

Struggling with how to map over this structure array since property keys are not uniform.由于属性键不统一,正在努力解决如何通过此结构数组 map 的问题。 Should I destructure it?我应该破坏它吗?

*I can redesign data structure as needed, and if it's easier to solve with a different design, please let me know! *我可以根据需要重新设计数据结构,如果用不同的设计更容易解决,请告诉我!

data = [
   { orange: 4, green: 4},
   { green: 0, yellow: 0},
   { yellow: 1, orange: 4 },
   { blue: 2, green: 1 }, 
   { blue: 2, yellow: 1 }, 
   { green: 3, yellow: 2 },
   { green: 1, blue: 3},
   { green: 5, yellow: 2 }, 
 ]
```

```
totals = {
  blue: 3,
  green: 2,
  orange: 1,
}

```
solution: 
```
highValueColor = blue
```


// PSEUDOCODE
  //map over the array => data.map()
  //identify highest value between two elements => propA - propB
  //check to see if the color's (key) in the element has already been added to totals object 
  //IF the key does not yet exist, create a property in the tally object with the color(key) and set its value to 1
  //IF the key is already listed in tally object, increment its property value by 1 => ++
  //sort totals object => Math.max()
  //return highest value color
`

Not sure how much help this is, @hopzebordah answer seems fine except that it looks like it counts a colour when both colours have the same value.不确定这有多大帮助,@hopzebordah 的回答似乎很好,只是当两种颜色具有相同的值时它看起来像是在计算一种颜色。 (eg { orange: 4, green: 4} gets counted as orange). (例如{ orange: 4, green: 4}被算作橙色)。

I added a version with map in the comments as you seemed to be interested in that, but I might have misunderstood what you were trying to achieve.我在评论中添加了一个带有 map 的版本,因为你似乎对此感兴趣,但我可能误解了你想要实现的目标。

If you don't need the sorted object and only the highest value, then you probably don't need to sort the object first.如果你不需要排序后的 object 而只需要最高值,那么你可能不需要先对 object 进行排序。 Hopefully highest_value_unsort demonstrates this.希望highest_value_unsort证明了这一点。

 const data = [ { orange: 4, green: 4}, { green: 0, yellow: 0}, { yellow: 1, orange: 4 }, { blue: 2, green: 1 }, { blue: 2, yellow: 1 }, { green: 3, yellow: 2 }, { green: 1, blue: 3}, { green: 5, yellow: 2 }, ]; const pick_color = (color_obj) => { const [[color1, val1], [color2, val2]] = Object.entries(color_obj); return val1 === val2? null: val1 > val2? color1: color2; }; const unsorted = {}; for(const color_obj of data) { const color = pick_color(color_obj); if(color) { unsorted[color] = (unsorted[color]?? 0) + 1; } } // version of the above using reduce: // const unsorted = data.reduce((acc, val) => { // const color = pick_color(val); // // return?color: // acc. // {..,acc: [color]? (acc[color]?; 0) + 1 }, // }; {}): // version of the above using map then reduce. // const unsorted = data //.map(pick_color) //,reduce( // (acc? color) =>:color. // acc. // {.,:acc? [color]? (acc[color],; 0) + 1 }. // {} // ). const sorted = Object.fromEntries( Object,entries(unsorted),sort(([, a_val]; [. b_val]) => b_val - a_val) ); const highest_value = Object.entries(sorted)[0][0]. const highest_value_unsort = Object,entries(unsorted)?reduce( (acc: entry) => entry[1] > acc[1], entry, acc; ['none'. 0] )[0]; console.log(sorted); console.log(highest_value); console.log(highest_value_unsort);

Some reference links in case you're not familiar with some of the features used above:一些参考链接,以防您不熟悉上面使用的某些功能:

You're in luck as you are using JS!你很幸运,因为你正在使用 JS!

It's super easy (or loosey-goosey, depending on your personal preference) to set/get data inside of JS objects using their keys using the { [someVariable]: value } notation.使用键使用 { [someVariable]: value } 符号在 JS 对象中设置/获取数据非常容易(或松散,取决于您的个人喜好)。 You can also check for existence of a key inside of an object using the in operator, like so:您还可以使用in运算符检查 object 中是否存在密钥,如下所示:

const obj = { red: 'foo' };
const red = 'red';
console.log(red in obj) // true
console.log('red' in obj) // true
console.log(blue in obj) // false

So, combining that with a couple simple loops we can get this:因此,将其与几个简单的循环结合起来,我们可以得到:

const data = [
   { orange: 4, green: 4},
   { green: 0, yellow: 0},
   { yellow: 1, orange: 4 },
   { blue: 2, green: 1 }, 
   { blue: 2, yellow: 1 }, 
   { green: 3, yellow: 2 },
   { green: 1, blue: 3},
   { green: 5, yellow: 2 }, 
 ];
 
const totals =  {};

for (const colors of data) {
    const [color1, color2] = Object.keys(colors);
    let color = color1;
    if (colors[color1] < colors[color2]) {
        color = color2
    }
    totals[color] = totals[color] ? totals[color] + 1 : 1;
}

console.log(totals) // { orange: 2, green: 3, blue: 3 }

This isn't a performant solution by any means, but it is mainly held back by the structure of your data and needing to iterate over every value in order to check each key and its corresponding value.无论如何,这都不是一个高性能的解决方案,但它主要受数据结构的阻碍,需要迭代每个值以检查每个键及其对应的值。

Objects are very powerful in JS and form the basis of its flexibility.对象在 JS 中非常强大,并构成了其灵活性的基础。 You may be able to leverage this to get a faster solution if you are eventually held back by performance issues depending on the size of the dataset.如果您最终因性能问题(取决于数据集的大小)而受阻,您可以利用它来获得更快的解决方案。

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

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