[英]Typescript get distinct values from an object
How do I write select distinct country, state from myObject
in javascript.如何在 javascript 中select distinct country, state from myObject
中select distinct country, state from myObject
。
Array.from(new Set(myObject.map(item => item.country)))
would return distinct countries.. How do I add countries, states and other columns in map??? Array.from(new Set(myObject.map(item => item.country)))
将返回不同的国家。我如何在地图中添加国家、州和其他列???
Input data:输入数据:
const myObject = [
{
country: 'USA',
state: 'Missouri',
county: 'County1',
},
{
country: 'USA',
state: 'Missouri',
county: 'County2',
},
{
country: 'Canada',
state: 'Alberta',
county: 'County3',
},
];
To get unique countries, I would write Array.from(new Set(myObject.map(item => item.country))) The result would be ['USA', 'Canada']为了获得独特的国家,我会写 Array.from(new Set(myObject.map(item => item.country))) 结果是 ['USA', 'Canada']
What should I write if want the result to be如果想要结果我应该写什么
[
{
country: 'USA',
state: 'Missouri',
},
{
country: 'Canada',
state: 'Alberta',
},
]
This contains unique country and state combinations这包含独特的国家和州组合
The following code should take an array of objects and a list of keys of those objects, and return an array of objects representing the distinct values for that set of keys.以下代码应采用对象数组和这些对象的键列表,并返回一个对象数组,表示该组键的不同值。 I assume that the type of properties at those keys will only be string
, number
, or boolean
.我假设这些键的属性类型只会是string
、 number
或boolean
。
function distinct<T extends Record<K, string | number | boolean>,
K extends keyof T>(arr: T[], ...keys: K[]): Pick<T, K>[] {
const key = (obj: T) => JSON.stringify(keys.map(k => obj[k]));
const val = (obj: T) => keys.reduce((a, k) => (a[k] = obj[k], a), {} as Pick<T, K>);
const dict = arr.reduce((a, t) => (a[key(t)] = val(t), a), {} as { [k: string]: Pick<T, K> })
return Object.values(dict);
}
The idea is to take each object in the array, serialize the tuple of its properties at the keys in question with JSON.stringify()
, and use this serialized string as a dictionary key.这个想法是获取数组中的每个对象,使用JSON.stringify()
在相关键处序列化其属性的元组,并将这个序列化的字符串用作字典键。 The value we put at that key is an object consisting of just the values at those properties.我们放置在该键上的值是一个仅由这些属性的值组成的对象。 By using a dictionary, we guarantee that only one object will appear for each distinct set of properties at the keys we care about.通过使用字典,我们保证对于我们关心的键处的每个不同的属性集,只会出现一个对象。 Then we turn the values of this dictionary into an array.然后我们把这个字典的值变成一个数组。
If I test it on your myObject
example, this is what comes out:如果我在您的myObject
示例上对其进行测试,结果如下:
const result = distinct(myObject, "country", "state");
console.log(result);
/* [{ "country": "USA", "state": "Missouri" }, { "country": "Canada", "state": "Alberta" }] */
which is what you wanted.这就是你想要的。 Let's also test it on some type and array that I made up now:让我们也在我现在编写的某种类型和数组上测试它:
interface MyObject {
country: string,
state: string,
age: number,
name: string
}
const arr: MyObject[] = [
{ name: "Alice", age: 35, country: "USA", state: "MA" },
{ name: "Bob", age: 40, country: "USA", state: "MI" },
{ name: "Carmen", age: 35, country: "Mexico", state: "BC" },
{ name: "Danilo", age: 35, country: "Mexico", state: "MI" }
]
So we have an array of MyObject
.所以我们有一个MyObject
数组。 Let's get the distinct country
values:让我们获得不同的country
值:
const distinctCountries = distinct(arr, "country"); // Array<{country: string}>
console.log(distinctCountries); // [{ "country": "USA" }, { "country": "Mexico" }]
console.log(distinctCountries.map(x => x.country)); // USA, Mexico
Notice how what comes out is an array of {country: string}
values.注意输出的是一个{country: string}
值数组。 You can use map()
to turn that into just an array of string
s.您可以使用map()
将其转换为string
数组。 Let's get the distinct country
and state
values:让我们获得不同的country
state
值:
const distinctCountriesAndStates = distinct(arr, "country", "state");
console.log(distinctCountriesAndStates);
/* [{ "country": "USA", "state": "MA" }, { "country": "USA", "state": "MI" },
{ "country": "Mexico", "state": "BC" }, { "country": "Mexico", "state": "MI" }] */
Here it's an array of {country: string, state: string}
objects.这是一个{country: string, state: string}
对象数组。 Not sure how you want to represent those, but you can use map()
to massage them as you see fit.不确定你想如何表示这些,但你可以使用map()
来按你认为合适的方式按摩它们。 Finally let's get the distinct country
and age
values:最后让我们得到不同的country
和age
值:
const distinctAgesAndCountries = distinct(arr, "country", "age");
console.log(distinctAgesAndCountries);
/* [{ "country": "USA", "age": 35 }, { "country": "USA", "age": 40 },
{ "country": "Mexico", "age": 35 }] */
That's an array of {country: string, age: number}
objects.这是一个{country: string, age: number}
对象数组。
Anyway, hope that gives you some direction.无论如何,希望能给你一些指导。
Base on referenced answer you can use Map
and spread operator
as below根据参考答案,您可以使用Map
和spread operator
,如下所示
https://stackoverflow.com/a/63274702/4964569 https://stackoverflow.com/a/63274702/4964569
const myObject = [ { country: 'USA', state: 'Missouri', county: 'County1' }, { country: 'USA', state: 'Missouri', county: 'County2' }, { country: 'Canada', state: 'Alberta', county: 'County3' }, ]; let data = new Map(); for (let obj of myObject) { delete obj.county; data.set(obj.country, obj); } let unique = [...data.values()]; console.log(unique);
Below is a solution using reduce;以下是使用reduce的解决方案;
const myObject = [ { country: 'USA', state: 'Missouri', county: 'County1' }, { country: 'USA', state: 'Missouri', county: 'County2' }, { country: 'Canada', state: 'Alberta', county: 'County3' }, ]; const unique = myObject.reduce((prev, {country, state}) => prev.some(x => x.country === country && x.state === state )? prev: [...prev, {country, state} ], []) console.log(unique )
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.