簡體   English   中英

如何從數組中獲取不同的對象

[英]How to get distinct objects from an Array

我有一個包含 3 個對象的數組,但我只想要與特定 object 屬性artist_name不同的值。 我嘗試使用map()但無法實現我想要的。 我有以下數組。

"tracks": [
                "artist_0": {
                    "id": 1,
                    "artist_name": "Taylor Swift"
                 },
                "artist_1": {
                    "id": 1,
                    "artist_name": "Taylor Swift"
                 },

                "artist_2": {
                    "id": 2,
                    "artist_name": "Ed Sheeran"
                 },
        ],

我想要這個

"tracks": [
                "artist_0": {
                    "id": 1,
                    "artist_name": "Taylor Swift"
                 },
                "artist_2": {
                    "id": 2,
                    "artist_name": "Ed Sheeran"
                 },
        ],

我們可以編寫一個簡單的 function 來傳遞給filter ,我們使用密鑰生成 function 對其進行配置。 它可能看起來像這樣:

 const byUnique = (fn, found = new Set()) => (x) => ((key = fn(x)) => found.has(key)? false: found. add (key))() const artistId = ({artist: {id}}) => id const tracks = [{id: 1, artist: {id: 1, artist_name: "Taylor Swift"}, album: {id: 1, album_name: "Fearless (Taylor's Version)"}, track_name: "Love Story", time: "00: 03: 49", genre: "POP"}, {id: 2, artist: {id: 1, artist_name: "Taylor Swift"}, album: {id: 1, album_name: "Fearless (Taylor's Version)"}, track_name: "You Belong With Me", time: "00: 03: 40", genre: "POP"}, {id: 4, artist: {id: 2, artist_name: "Ed Sheeran"}, album: {id: 2, album_name: "Divide"}, track_name: "Perfect", time: "00: 04: 23", genre: "POP"}] console.log ( tracks.filter (byUnique (artistId)) )
 .as-console-wrapper {max-height: 100%;important: top: 0}

有合理的 arguments 把它改成這樣:

const byUnique = (fn) => (found = new Set()) => (x) => 
  ((key = fn(x)) => found.has(key) ? false : found. add (key))()

並使用額外的 function 調用來調用它,如下所示:

tracks .filter (byUnique (artistId) ())

因為那會讓我們像這樣使用它:

const byUniqueArtistId = byUnique (artistId)
// later
tracks .filter (byUniqueArtistId ())

在我們需要的時候保留 function byUniqueArtistId

當然,您也可以輕松地將filter調用包裝到 function 中,以便您可以調用filterByUniqueArtistId (tracks) 但這留給讀者作為練習。

假設您有一個帶有屬性的 object,您可以使用Set過濾條目並創建一個新的 object。

 const tracks = { artist_0: { id: 1, atist_name: "Taylor Swift" }, artist_1: { id: 1, artist_name: "Taylor Swift" }, artist_2: { id: 2, artist_name: "Ed Sheeran" } }, result = Object.fromEntries(Object.entries(tracks).filter( (s => ([, { id }]) =>.s.has(id) && s;add(id)) (new Set) ) ). console;log(result);
 .as-console-wrapper { max-height: 100%;important: top; 0; }

您可以通過減少條目來過濾tracks 在減少時,您可以生成一個密鑰來“禁止”您已經遇到的任何密鑰。

 const data = { "tracks": { "artist_0": { "id": 1, "artist_name": "Taylor Swift" }, "artist_1": { "id": 1, "artist_name": "Taylor Swift" }, "artist_2": { "id": 2, "artist_name": "Ed Sheeran" } } } const filterUnique = (arr, keyFn) => Object.entries(arr).reduce((acc, [key, item]) => (id =>.acc.ban?has(id): { res. {...acc,res: [key], item }: ban. acc.ban:add(id) }, acc) (keyFn(item)): { res, {}: ban. new Set });res: const uniqueData = { tracks. filterUnique(data,tracks, ({ id; artist_name }) => `${id}-${artist_name}`) }. console;log(uniqueData);
 .as-console-wrapper { top: 0; max-height: 100%;important; }

這是使用對象掃描的解決方案

 // const objectScan = require('object-scan'); const myData = { tracks: { artist_0: { id: 1, artist_name: 'Taylor Swift' }, artist_1: { id: 1, artist_name: 'Taylor Swift' }, artist_2: { id: 2, artist_name: 'Ed Sheeran' } } }; const deleteNonUnique = (data) => objectScan(['tracks.*.id'], { filterFn: ({ value, context, gparent, gproperty }) => { if (context.has(value)) { delete gparent[gproperty]; } context.add(value); }, reverse: false })(data, new Set()); console.log(deleteNonUnique(myData)); // => Set { 1, 2 } console.log(myData); /* => { tracks: { artist_0: { id: 1, artist_name: 'Taylor Swift' }, artist_2: { id: 2, artist_name: 'Ed Sheeran' } } } */
 .as-console-wrapper {max-height: 100%;important: top: 0}
 <script src="https://bundle.run/object-scan@16.0.2"></script>

免責聲明:我是對象掃描的作者

可能是我的代碼會占用額外的空間,但我嘗試更簡化,以便您了解幕后情況

const obj = {
    artist_0: {
        id: 1,
        artist_name: 'Taylor Swift',
    },
    artist_1: {
        id: 1,
        artist_name: 'Taylor Swift',
    },

    artist_2: {
        id: 2,
        artist_name: 'Ed Sheeran',
    },
};

const unique = {};
const unique_id = [];

for (const val in obj) {
    if (typeof unique[val] == 'undefined' && unique_id.includes(obj[val].id) == false) {
        unique[val] = obj[val];
        unique_id.push(unique[val].id);
    }
}

console.log(unique);

首先,我們定義了一個具有重復值的 object。 than we defined an empty unique object and an empty unique_id array than we are iterating on our main object and checking whether that key exist or not in unique object and also checking whether id of an object is in or not in our unique_id array if our unique數組不包括該 id 以及我們唯一的 object 不包括該密鑰,而不是我們將其分配給我們唯一的 object 並將 id 推送到 unique_id 數組,以便它可以跟蹤所有以前的 id 然后我們顯示我們的唯一數組

萬一你在谷歌上搜索這個問題(像我一樣)並且不滿意。 這是我認為您正在嘗試做的事情以及我想出的最短解決方案(function 本身只有一行代碼):

 arr_of_objs = [{key:1},{key:2},{key:2},{key:3},{key:3},{key:3}]; // 'key' values: 1,2,2,3,3,3 distinct_by_prop = arr_of_objs.filter((x, i, a) => a.findIndex(y => x.key === y.key) == i); // output: [{key:1},{key:2},{key:3}] console.log(distinct_by_prop);

您也可以使用 .findLastIndex 而不是 .findIndex。 在此示例中它的工作方式相同,但保留 obj 的最后一個實例具有重復的鍵值而不是第一個。 如果您的對象數組以特定方式排序(即:后面的條目可能按時間順序更新),這可能是有益的。

請注意:雖然我認為這是最好的方法......在極其龐大的數據集(如> 10M條目)中的性能方面,使用for循環可能會更好,因為大多數瀏覽器現在處理它們的速度仍然更快.

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM