【问题标题】:How to filter an array of objects and order them based on how many times they show up in array如何过滤对象数组并根据它们在数组中出现的次数对它们进行排序
【发布时间】:2020-11-16 07:47:37
【问题描述】:

我有一组用户对象,其中一些出现多次。我正在尝试计算每个唯一用户对象在数组中出现的次数,并对它们重新排序,以使出现频率最高的用户在数组中排在第一位,而在数组中出现最少的用户在数组中显示在最后。

const users = 
[
   {id: "0f933bbd-d1fb-4ad5-80f0-661c3c0aa2f8", handle: "lisa", email: "lisa@gmail.com", createdAt: 1593894321997},
 
   {id: "bbfc927c-f3d4-4cdd-b872-9cb233a194aa", handle: "jisoo", email: "jisoo@gmail.com", createdAt: 1592452421714},

   {id: "be942039-6a59-46a4-9f92-1f7808b20c2f", handle: "unnieJennie", email: "jennie@gmail.com", createdAt: 1593894227232},

   {id: "0f933bbd-d1fb-4ad5-80f0-661c3c0aa2f8", handle: "lisa", email: "lisa@gmail.com", createdAt: 1593894321997},

   {id: "1d1e31cd-eff2-47de-b46d-4d45bb2dd97f", handle: "kawikaLovesKpop", email: "kawika@gmail.com", createdAt: 1593894550566},

   {id: "be942039-6a59-46a4-9f92-1f7808b20c2f", handle: "unnieJennie", email: "jennie@gmail.com", createdAt: 1593894227232},

   {id: "0f933bbd-d1fb-4ad5-80f0-661c3c0aa2f8", handle: "lisa", email: "lisa@gmail.com", createdAt: 1593894321997},

   {id: "1d1e31cd-eff2-47de-b46d-4d45bb2dd97f", handle: "kawikaLovesKpop", email: "kawika@gmail.com", createdAt: 1593894550566},

   {id: "be942039-6a59-46a4-9f92-1f7808b20c2f", handle: "unnieJennie", email: "jennie@gmail.com", createdAt: 1593894227232}
]

我尝试过将 countBy 方法与 lodash 一起使用

const bestMatched = countBy(users, "handle");

返回

{lisa: 3, jisoo: 1, unnieJennie: 3, kawikaLovesKpop: 2}

我仍然需要访问包含所有对象键和值的用户数组。

【问题讨论】:

    标签: javascript arrays sorting object


    【解决方案1】:

    您可以按位使用NOT 来执行此操作,因为~undefined = -1 并且我们需要一个对象来存储我们的结果:

    const result = users.reduce((m,{handle})=>({...m, [handle]:-~m[handle]}), {})
    

    试试看:

    const users = 
    [
       {id: "0f933bbd-d1fb-4ad5-80f0-661c3c0aa2f8", handle: "lisa", email: "lisa@gmail.com", createdAt: 1593894321997},
     
       {id: "bbfc927c-f3d4-4cdd-b872-9cb233a194aa", handle: "jisoo", email: "jisoo@gmail.com", createdAt: 1592452421714},
    
       {id: "be942039-6a59-46a4-9f92-1f7808b20c2f", handle: "unnieJennie", email: "jennie@gmail.com", createdAt: 1593894227232},
    
       {id: "0f933bbd-d1fb-4ad5-80f0-661c3c0aa2f8", handle: "lisa", email: "lisa@gmail.com", createdAt: 1593894321997},
    
       {id: "1d1e31cd-eff2-47de-b46d-4d45bb2dd97f", handle: "kawikaLovesKpop", email: "kawika@gmail.com", createdAt: 1593894550566},
    
       {id: "be942039-6a59-46a4-9f92-1f7808b20c2f", handle: "unnieJennie", email: "jennie@gmail.com", createdAt: 1593894227232},
    
       {id: "0f933bbd-d1fb-4ad5-80f0-661c3c0aa2f8", handle: "lisa", email: "lisa@gmail.com", createdAt: 1593894321997},
    
       {id: "1d1e31cd-eff2-47de-b46d-4d45bb2dd97f", handle: "kawikaLovesKpop", email: "kawika@gmail.com", createdAt: 1593894550566},
    
       {id: "be942039-6a59-46a4-9f92-1f7808b20c2f", handle: "unnieJennie", email: "jennie@gmail.com", createdAt: 1593894227232}
    ]
    
    const result = users.reduce((m,{handle})=>({...m, [handle]:-~m[handle]}), {})
    
    console.log({result})

    由于对象是无序的,所以如果你想有一个有序的集合,你需要使用数组。

    const result = users.reduce((m,{handle})=>({...m, [handle]:-~m[handle]}), {})
    Object.keys(result).sort((a,b)=>result[a]-result[b]).map(key=>({[key]:result[key]}))
    

    【讨论】:

    • ~在那里做什么?
    • @MoHradA 基本上,我们将初始化一个对象{} 然后我们将计算每个元素的出现次数,如果键之前不存在(未定义)那么它应该是1(按位NOT我们可以这样做 ~undefined = -1 和 -~undefined = 1),如果键存在,那么它应该是前一个 + 1
    • 谢谢,很好。由于 OP 想要对结果进行排序,我建议也添加该逻辑
    【解决方案2】:

    试试这个:

    let counterObj = {}
    
    for (user of users){
        counterObj[user.handle] = 1 + (counterObj[user.handle] || 0)
    }
    
    console.log(counterObj)

    【讨论】:

    • 感谢您的快速响应!这也返回与上面的 countBy 方法相同的解决方案:``` {lisa: 3, jisoo: 1, unnieJennie: 3, kawik​​aLovesKpop: 2} ``` 我正在尝试返回另一个数组,其中包含用户“lisa”和“ unnieJennie”第一次出现,因为他们出现了 3 次,“kawik​​a”第二次出现,因为他出现了两次,“jisoo”最后一次出现了。
    【解决方案3】:

    const users = 
    [
       {id: "0f933bbd-d1fb-4ad5-80f0-661c3c0aa2f8", handle: "lisa", email: "lisa@gmail.com", createdAt: 1593894321997},
     
       {id: "bbfc927c-f3d4-4cdd-b872-9cb233a194aa", handle: "jisoo", email: "jisoo@gmail.com", createdAt: 1592452421714},
    
       {id: "be942039-6a59-46a4-9f92-1f7808b20c2f", handle: "unnieJennie", email: "jennie@gmail.com", createdAt: 1593894227232},
    
       {id: "0f933bbd-d1fb-4ad5-80f0-661c3c0aa2f8", handle: "lisa", email: "lisa@gmail.com", createdAt: 1593894321997},
    
       {id: "1d1e31cd-eff2-47de-b46d-4d45bb2dd97f", handle: "kawikaLovesKpop", email: "kawika@gmail.com", createdAt: 1593894550566},
    
       {id: "be942039-6a59-46a4-9f92-1f7808b20c2f", handle: "unnieJennie", email: "jennie@gmail.com", createdAt: 1593894227232},
    
       {id: "0f933bbd-d1fb-4ad5-80f0-661c3c0aa2f8", handle: "lisa", email: "lisa@gmail.com", createdAt: 1593894321997},
    
       {id: "1d1e31cd-eff2-47de-b46d-4d45bb2dd97f", handle: "kawikaLovesKpop", email: "kawika@gmail.com", createdAt: 1593894550566},
    
       {id: "be942039-6a59-46a4-9f92-1f7808b20c2f", handle: "unnieJennie", email: "jennie@gmail.com", createdAt: 1593894227232}
    ]
    
    ob={lisa: 3, jisoo: 1, unnieJennie: 3, kawikaLovesKpop: 2}
    map=new Map()
    users.map(x=>map.set(x.handle,x))
    res=Object.entries(ob).sort((a,b)=>b[1]-a[1])
    .flatMap(o=>Array(o[1]).fill(map.get(o[0])))
    
    
    console.log(res)

    【讨论】:

      【解决方案4】:

      我相信这可能就是您想要的。 JSON 中也有一些错误,但现在应该没问题了。

      const users = [
        {
          id: '0f933bbd-d1fb-4ad5-80f0-661c3c0aa2f8',
          handle: 'lisa',
          email: 'lisa@gmail.com',
          createdAt: 1593894321997,
        },
        {
          id: 'bbfc927c-f3d4-4cdd-b872-9cb233a194aa',
          handle: 'jisoo',
          email: 'jisoo@gmail.com',
          createdAt: 1592452421714,
        },
        {
          id: 'be942039-6a59-46a4-9f92-1f7808b20c2f',
          handle: 'unnieJennie',
          email: 'jennie@gmail.com',
          createdAt: 1593894227232,
        },
        {
          id: '0f933bbd-d1fb-4ad5-80f0-661c3c0aa2f8',
          handle: 'lisa',
          email: 'lisa@gmail.com',
          createdAt: 1593894321997,
        },
        {
          id: '1d1e31cd-eff2-47de-b46d-4d45bb2dd97f',
          handle: 'kawikaLovesKpop',
          email: 'kawika@gmail.com',
          createdAt: 1593894550566,
        },
        {
          id: 'be942039-6a59-46a4-9f92-1f7808b20c2f',
          handle: 'unnieJennie',
          email: 'jennie@gmail.com',
          createdAt: 1593894227232,
        },
        {
          id: '0f933bbd-d1fb-4ad5-80f0-661c3c0aa2f8',
          handle: 'lisa',
          email: 'lisa@gmail.com',
          createdAt: 1593894321997,
        },
        {
          id: '1d1e31cd-eff2-47de-b46d-4d45bb2dd97f',
          handle: 'kawikaLovesKpop',
          email: 'kawika@gmail.com',
          createdAt: 1593894550566,
        },
        {
          id: 'be942039-6a59-46a4-9f92-1f7808b20c2f',
          handle: 'unnieJennie',
          email: 'jennie@gmail.com',
          createdAt: 1593894227232,
        },
      ];
      
      function sort(jsonArray) {
        var containerArray = [];
        jsonArray.map((item, index) => {
          if (item === 'null') {
          } else {
            var newArray = [];
            var itemHandle = item.handle;
            jsonArray.map((i, index) => {
              if (itemHandle === i.handle && itemHandle !== 'null') {
                newArray.push(i);
                jsonArray.splice(index, 1, 'null');
              }
            });
            jsonArray.splice(index, 1, 'null');
            containerArray.push(newArray);
          }
        });
        return containerArray;
      }
      
      var finalArray = sort(users);
      
      //Sorts the finalArray by highest occurrence to lowest
      finalArray.sort(function(a,b){
        return b.length - a.length
      })
      
      console.log(finalArray)
      

      将对象放在一起,以便您仍然可以通过点表示法访问它们的属性。

      【讨论】:

      • 循环拼接数组是一种非常糟糕的做法。此外,您似乎使用 map where find 或 forEach 会更实用。仅使用 map() 来创建循环也是一种不好的做法
      • @charlietfl 应该用什么代替拼接?
      猜你喜欢
      • 2017-09-20
      • 1970-01-01
      • 2020-08-09
      • 1970-01-01
      • 1970-01-01
      • 2010-09-06
      • 2017-06-13
      • 2023-03-18
      • 2019-09-28
      相关资源
      最近更新 更多