嵌套循环遍历两个数组,以便按类别排序

Nested Loop through the two array for sort by category

提问人:Otabek Amonov 提问时间:1/11/2023 最后编辑:vanowmOtabek Amonov 更新时间:1/14/2023 访问量:196

问:

let arr = [
     {
          name: 'siggaret',
          type: 'tobbako'
     },
     {
          name: 'fanta',
          type: 'liquid'
     },
     {
          name: 'potato',
          type: 'vegetables'
     },
     {
          name: 'tvorog',
          type: 'milk'
     },
     {
          name: 'steak',
          type: 'meat'
     },
     {
          name: 'kent',
          type: 'tobbako'
     },
     {
          name: 'cola',
          type: 'liquid'
     },
     {
          name: 'potato',
          type: 'vegetables'
     },
     {
          name: 'tvorog',
          type: 'milk'
     },
     {
          name: 'steak',
          type: 'meat'
     },
     {
          name: 'sheep',
          type: 'meat'
     }
]

let categories = [
     {
          type: 'vegetables',
          arr: [],
          count: 0
     },
     {
          type: 'tobbako',
          arr: [],
          count: 0
     },
     {
          type: 'liquid',
          arr: [],
          count: 0
     },
     {
          type: 'other',
          arr: [],
          count: 0
     }
]

/*
    
*/


for (let item of arr) {
     for (let category of categories) {
          if(item.type === category.type){
               category.arr.push(item.name)
               category.count++
          } else {
               category.arr.push(item.name)
               category.count++
          }
     }
}

console.log(categories)

有项目没有添加到其他项目中?问题是什么?

我尝试按类别对所有项目进行排序。

嵌套循环效果不佳,但我尝试使用 for of 并且排序存在一些问题。

当我尝试按 item.name 和category.type排序时,所有项目的名称都会添加到所有类别中。

我有两个数组,我需要找到两者之间的差异并将它们显示在无序列表中。

我可以遍历单个匹配项的主数组,但我不知道如何遍历多个键值的主列表并有效地做到这一点。

以下是每个数组中键值的摘录:

JavaScript 数组对象 嵌套循环 for-of-loop

评论

1赞 vanowm 1/11/2023
问题尚不清楚...预期结果是什么?按类别排序:按类别名称的字母顺序排序,还是按计数排序?
0赞 Otabek Amonov 1/11/2023
我尝试通过对数组项进行排序来将数组项添加到类别中。

答:

0赞 Max Cruer 1/11/2023 #1

在代码中,两个分支都运行相同的代码。您应该删除该分支。if () { ... } else { ... }else { ... }

喜欢这个:

for (let item of arr) {
     for (let category of categories) {
          if (item.type === category.type){
               category.arr.push(item.name);
               category.count++;
          }
     }
}

评论

0赞 Otabek Amonov 1/11/2023
我这样做了,但其他人的 arr 是空洞的!!
0赞 Daksh Lohar 1/11/2023 #2

问题出在 else 语句中,基本上,你不需要 else 语句,因为如果你看到代码它们都是相同的,在你的情况下,你正在将项目添加到类别中,所以删除 else 语句:

for (let item of arr){
   for (let category of categories) {
      if(item.type === category.type){
          category.arr.push(item.name);
           category.count++;
        }
     }
  }
0赞 SwissCheese15 1/11/2023 #3

良好的开端。 问题出在您的 else 语句中。发生的情况是:

else {
    category.arr.push(item.name)
    category.count++
}

触发频率过高。每当类别不匹配时,都会推送它。

如何修复:您需要在该循环之外处理“推送到”其他人“部分。

评论

0赞 Otabek Amonov 1/11/2023
我如何理解???
1赞 vanowm 1/11/2023 #4

您可以将类别转换为一个对象,而不是遍历两个数组,其中类别类型是键,因此您可以只用作键:type

let arr = [
     {
          name: 'siggaret',
          type: 'tobbako'
     },
     {
          name: 'fanta',
          type: 'liquid'
     },
     {
          name: 'potato',
          type: 'vegetables'
     },
     {
          name: 'tvorog',
          type: 'milk'
     },
     {
          name: 'steak',
          type: 'meat'
     },
     {
          name: 'kent',
          type: 'tobbako'
     },
     {
          name: 'cola',
          type: 'liquid'
     },
     {
          name: 'potato',
          type: 'vegetables'
     },
     {
          name: 'tvorog',
          type: 'milk'
     },
     {
          name: 'steak',
          type: 'meat'
     },
     {
          name: 'sheep',
          type: 'meat'
     }
]

let categories = {
     'vegetables': {
          arr: [],
          count: 0
     },
     'tobbako': {
          arr: [],
          count: 0
     },
     'liquid': {
          arr: [],
          count: 0
     },
     'other': {
          arr: [],
          count: 0
     }
}


for (let item of arr) {
  //get category object or fallback to "other"
  const category = categories[item.type] || categories.other;
  category.arr.push(item.name)
  category.count++
}

console.log(categories)

// now we can get an array sorted by count of our categories name
const sortedByCount = Object.keys(categories) //get array of types
  .sort((a,b) => categories[b].count - categories[a].count) // sort by count
  .map(type => type + " = "  + categories[type].count); // append count

console.log("categories sorted by count", sortedByCount);

//or convert it into array w/sorted names
const categoriesArray = Object.keys(categories) //get array of types
  .map(type => //convert types into objects
  {
    const category = Object.assign({}, categories[type]); //clone object
  //  const category = categories[type]; //don't clone object
    category.type = type;

    category.arr = [...category.arr].sort(); //clone array and sort it
  //  category.arr.sort(); //sort array of names without clonning
    return category;
  })
  .sort((a,b) => b.count - a.count); //sort by count
console.log("categories as array sorted by count w / sorted names", categoriesArray);
.as-console-wrapper{top:0;max-height:unset!important;overflow:auto!important;}

0赞 PeterKA 1/11/2023 #5

您可以按如下方式使用 and 方法的组合,然后使用 with 对数组进行排序:Object.values()Array#reduce()sortmap

const 
    arr = [ { name: 'siggaret', type: 'tobbako' }, { name: 'fanta', type: 'liquid' }, { name: 'potato', type: 'vegetables' }, { name: 'tvorog', type: 'milk' }, { name: 'steak', type: 'meat' }, { name: 'kent', type: 'tobbako' }, { name: 'cola', type: 'liquid' }, { name: 'potato', type: 'vegetables' }, { name: 'tvorog', type: 'milk' }, { name: 'steak', type: 'meat' }, { name: 'sheep', type: 'meat' } ],
    
    categories = Object.values(
        arr.reduce(
            (acc,{name,type}) => 
              ({
                ...acc,[type]:{
                  type,
                  arr:[...(acc[type] && acc[type]?.arr || []),name],
                  count:(acc[type] && acc[type].count || 0) + 1
                }
              }), {}
        )
    )
    .sort((a,b) => a.type.localeCompare(b.type))
    .map(({type,arr,count}) => ({type,arr:arr.sort((a,b) => a.localeCompare(b)),count}));
    
    console.log( categories );