数组对象中提取其中一个属性变为新对象,剩下的属性再变成数组对象,然后根据提取的新对象去判断,如果相同则合并他们的数组对象。

本文介绍了一种使用JavaScript处理复杂JSON数组的方法,通过两步操作实现数据的去重和整合,适用于需要对大量数据进行快速整理的场景。

原始数据:

 第一步:

var Obj = jsonArr.map(item => {

      let obj = {

        work: []

      }

      obj.name = item.beginer

      obj.work.push(item)

      return obj

    })

    console.log(Obj);

200多条,只是遍历一遍,并提取其中name属性

 第二步(方法一):

if (Obj && Obj.length > 0) {

      var newArr = [];

      Obj.forEach(function (item) {

        var flag = true;

        if (newArr.length > 0) {

          // 此处 不能用foreach,不然没法使用break跳出循环

          for (var i = 0; i < newArr.length; i++) {

            if (newArr[i].name == item.name) {

              newArr[i].work.push(item.work[0])

              flag = false;

              break;

            }

          }

        }

        if (flag) {

          newArr.push(item)

        }

      })

    }

    console.log(newArr);

根据name,把name相同的都合并到了一起,只留下来一个name,重复的都去掉了,并且name相同的work属性的属性值全部合并在了一起

 

 方法二:

let newArr = jsonArr.reduce((total, item) => {

      let index = total.findIndex(it => it.name == item.beginer)

      if (index === -1)

        total.push({

          name: item.beginer,

          work: [item]

        });

      else total[index].work.push(item);

      return total

    }, [])

    console.log(newArr);

<think>嗯,我现在需要解决的问题是根据route数组中的对象的title属性和sidebar数组中元素的title属性来进行排序。首先,我需要理解这两个数组的结构以及它们之间的关系。 用户提到的是将route数组对象根据自身的title属性和sidebar数组中的元素的title属性来排序。这可能意味着需要按照sidebar数组中的title顺序来排列route数组中的元素。也就是说,sidebar数组中的title顺序决定了route数组中对应title对象的排序顺序。 首先,我需要明确两个数组的结构。假设route数组中的每个元素都有一个title属性,而sidebar数组中的每个元素也有一个title属性。可能的情况是,sidebar数组中的title顺序是预先定义好的,我们需要将route数组中的元素按照这个顺序排列。 例如,假设sidebar数组是这样的: sidebar = [ { title: '首页', path: '/' }, { title: '关于我们', path: '/about' }, { title: '联系我们', path: '/contact' } ] 而route数组可能包含更多或同样的元素,但顺序不同: route = [ { path: '/about', component: 'About', title: '关于我们' }, { path: '/', component: 'Home', title: '首页' }, { path: '/contact', component: 'Contact', title: '联系我们' }, { path: '/products', component: 'Products', title: '产品' } ] 现在的问题是将route数组按照sidebar中的title顺序排序。但注意到route数组中可能包含sidebar中没有的title(比如“产品”),这时候需要决定如何处理这些额外的元素。可能的做法是将它们放在排序后的数组末尾,或者保持原顺序,或者按其他方式处理。 接下来,我需要考虑如何实现这个排序。通常,在JavaScript中,可以使用数组的sort方法,并自定义比较函数。比较函数需要根据两个元素的title在sidebar中的索引来决定它们的顺序。 具体步骤如下: 1. 首先,将sidebar数组中的title提取出来,形成一个顺序数组。例如,['首页', '关于我们', '联系我们']。 2. 对于route数组中的每个元素,获取其title在sidebar顺序数组中的索引。如果不存在,可能赋予一个很大的,使其排在后面。 3. 在比较函数中,比较两个元素对应的索引,从而决定它们的顺序。 需要注意的是,可能存在route中的某些title在sidebar中不存在的情况,这时需要考虑这些元素的排序位置。例如,将它们排在最后,或者按照字母顺序排列。用户的需求可能希望这些元素保留在原位置,或者按照其他方式处理,但根据问题描述,可能应排在sidebar顺序之后。 此外,还需要处理重复的title或sidebar中可能存在多个相同title的情况。需要明确是否每个title在sidebar中只出现一次,或者如何处理这种情况。 假设sidebar中的title是唯一的,那么可以生成一个映射对象,将title映射到其索引,这样在查找时更高效。例如: const orderMap = {}; sidebar.forEach((item, index) => { orderMap[item.title] = index; }); 然后,在比较route中的元素时,对于每个元素的title,查找其在orderMap中的索引,如果不存在,则返回一个足够大的数字(如Infinity),以确保它们排在后面。 所以,比较函数可能是这样的: route.sort((a, b) => { const indexA = orderMap[a.title] !== undefined ? orderMap[a.title] : Infinity; const indexB = orderMap[b.title] !== undefined ? orderMap[b.title] : Infinity; return indexA - indexB; }); 这样,route中的元素将按照sidebar中的title顺序排列,不在sidebar中的元素会被排在最后,并且它们之间的相对顺序可能保持不变(因为如果它们的索引都是Infinity,那么它们的顺序由原数组中的位置决定,但sort方法是不稳定的,所以可能不会保留原顺序)。如果需要保持不在sidebar中的元素的原始顺序,可能需要使用稳定排序,或者记录原始位置,但JavaScript的sort本身不稳定,所以可能需要其他方法。 另一个情况是,route数组中的某些元素可能在sidebar中没有对应的title,这时候可能需要将它们保留在原来的位置,或者按其他规则处理。例如,用户可能希望这些元素出现在排序后的数组的末尾,但保持它们之间的相对顺序。这时候可能需要将数组分成两部分:一部分在sidebar中存在title的元素,按顺序排序;另一部分是不存在的,保持原顺序,然后合并这两部分。 例如: const orderedTitles = sidebar.map(item => item.title); const inOrder = route.filter(item => orderedTitles.includes(item.title)); const notInOrder = route.filter(item => !orderedTitles.includes(item.title)); 然后,对inOrder数组按照sidebar中的顺序排序,然后将notInOrder数组保持原顺序,合并两者。但这样处理的话,notInOrder中的元素可能不再保持它们在原route数组中的顺序,因为filter会遍历数组,保留原有顺序吗?是的,filter会按顺序将符合条件的元素放入数组。因此,notInOrder中的元素在原route数组中的相对顺序会被保留。 然后,对inOrder进行排序。这时候排序需要根据sidebar中的顺序,可以给每个元素添加一个排序键,比如根据sidebar中的索引,然后进行排序。 例如: const titleToIndex = new Map(); sidebar.forEach((item, index) => { titleToIndex.set(item.title, index); }); const inOrder = route.filter(item => titleToIndex.has(item.title)); inOrder.sort((a, b) => titleToIndex.get(a.title) - titleToIndex.get(b.title)); const sortedRoute = [...inOrder, ...notInOrder]; 这种方法可能更高效,因为它将数组分成两部分,仅对需要排序的部分进行处理,然后合并。同时,不在sidebar中的元素会保持原顺序出现在最后。 但需要注意,这种方法会改变原route数组中元素的顺序,将存在的元素提取出来排序,而将不存在的元素放在最后。这可能符合用户的需求,也可能不。例如,如果route中存在多个元素在sidebar中,且它们的顺序在sidebar中是分散的,但需要严格按照sidebar中的顺序排列,那么这种方法可行。 另一个需要考虑的是,route中的元素可能在sidebar中存在多个相同的title,但这种情况是否可能?根据问题描述,可能假设title在sidebar中是唯一的,否则可能需要其他处理方式。 总结可能的步骤: 1. 从sidebar数组提取title的顺序,并建立一个title到索引的映射。 2. 将route数组分成两部分:存在于sidebar中的title和不存在于sidebar中的。 3. 对存在的那部分按照sidebar中的顺序排序。 4. 合并两部分,不存在的那部分可以按原顺序放在后面,或者按其他方式处理。 5. 最终得到排序后的route数组。 现在需要考虑用户的具体需求,比如如何处理不在sidebar中的元素,是否需要保持它们的原顺序。如果用户希望这些元素按原顺序排在后面,那么上述方法是合适的。 例如,假设用户给出的示例中,route有一个title为“产品”的元素,不在sidebar中,那么在排序后的数组中,它会被放在最后。 可能的实现代码如下: function sortRoutesBySidebar(routes, sidebar) { // 创建title到索引的映射 const titleIndexMap = new Map(); sidebar.forEach((item, index) => { titleIndexMap.set(item.title, index); }); // 分割数组 const inSidebar = []; const notInSidebar = []; routes.forEach(route => { if (titleIndexMap.has(route.title)) { inSidebar.push(route); } else { notInSidebar.push(route); } }); // 按照sidebar中的顺序排序 inSidebar.sort((a, b) => { return titleIndexMap.get(a.title) - titleIndexMap.get(b.title); }); // 合并数组 return [...inSidebar, ...notInSidebar]; } 这样,返回的数组就是按照sidebar中的title顺序排列的route元素,后面跟着不在sidebar中的元素,保持原顺序。 需要注意的是,这种方法假设每个route元素都有一个title属性,并且sidebar中的每个元素也有title属性。如果存在route中的title在sidebar中出现多次,那么会根据sidebar中的一个出现的索引来排序,但这种情况可能需要进一步处理,但通常sidebar中的title应该是唯一的。 测试一下这个函数是否符合预期: 例如,route数组为: [ {title: '关于我们'}, {title: '首页'}, {title: '产品'}, {title: '联系我们'} ] sidebar数组为: [ {title: '首页'}, {title: '关于我们'}, {title: '联系我们'} ] 经过排序后,应该得到顺序:首页、关于我们、联系我们,然后是产品。但根据上述代码,inSidebar中的元素会被排序为首页(索引0)、关于我们(索引1)、联系我们(索引2)。然后合并后的数组是这三个加上产品。但原route中的顺序是关于我们、首页、联系我们,产品。根据代码中的分割,inSidebar中的元素是这三个,然后排序时根据sidebar中的顺序,首页的索引是0,关于我们是1,联系我们是2。所以排序后的inSidebar数组应该是首页,关于我们,联系我们。然后加上产品。因此,结果应为: [ {title: '首页'}, {title: '关于我们'}, {title: '联系我们'}, {title: '产品'} ] 但原route数组中关于我们的顺序是第一个,首页是第二个,所以分割后的inSidebar数组包含这三个元素,顺序是原数组中的顺序,即关于我们、首页、联系我们,然后在排序时,首页的索引是0,所以排序后的inSidebar数组顺序变为首页(索引0)、关于我们(索引1)、联系我们(索引2)。因此,正确排序。 这说明代码是可行的。 另一种情况,如果route中存在多个相同的title,比如两个“首页”,则它们都会被放在inSidebar数组中,并根据sidebar中的顺序排序,这样它们的相对顺序可能会改变,因为sort方法可能改变它们的顺序。但JavaScript的sort是不稳定的,所以如果原数组中两个相同的元素的顺序可能不保留。如果需要保持原来的相对顺序,可以考虑使用稳定排序,或者在排序时添加辅助索引。 不过用户的问题中没有提到这种情况,所以可能不需要处理。 综上,解决方案是: 1. 创建title到索引的映射。 2. 分割route数组为存在于sidebar和不存在于sidebar的两部分。 3. 对存在于sidebar中的部分按照映射中的索引排序。 4. 合并两部分,将不存在于sidebar中的部分放在最后,保持原顺序。 这样就能实现根据sidebar数组的title顺序对route数组进行排序。</think>要根据 `route` 数组对象的 `title` 属性,按照 `sidebar` 数组中元素的 `title` 顺序进行排序,同时将不在 `sidebar` 中的 `title` 元素保留在末尾,可以按以下步骤实现: ### 实现步骤 1. **提取 `sidebar` 的顺序映射**:将 `sidebar` 数组的 `title` 转换为 `{ title: index }` 的键对,用于快速查询顺序。 2. **分割 `route` 数组**:将 `route` 分为两部分: - **存在于 `sidebar` 中的元素**:按 `sidebar` 的顺序排序。 - **不存在于 `sidebar` 中的元素**:保留原顺序,放在末尾。 3. **合并结果**:将两部分数组合并,得到最终排序后的数组。 ### 代码实现 ```javascript function sortRoutesBySidebar(routes, sidebar) { // 1. 创建 title 到索引的映射 const titleIndexMap = new Map(); sidebar.forEach((item, index) => { titleIndexMap.set(item.title, index); }); // 2. 分割 route 数组 const inSidebar = []; const notInSidebar = []; routes.forEach(route => { if (titleIndexMap.has(route.title)) { inSidebar.push(route); } else { notInSidebar.push(route); } }); // 3. 按 sidebar 的顺序排序 inSidebar.sort((a, b) => { return titleIndexMap.get(a.title) - titleIndexMap.get(b.title); }); // 4. 合并并返回结果 return [...inSidebar, ...notInSidebar]; } ``` ### 使用示例 ```javascript const sidebar = [ { title: '首页', path: '/' }, { title: '关于我们', path: '/about' }, { title: '联系我们', path: '/contact' } ]; const route = [ { path: '/about', component: 'About', title: '关于我们' }, { path: '/', component: 'Home', title: '首页' }, { path: '/contact', component: 'Contact', title: '联系我们' }, { path: '/products', component: 'Products', title: '产品' } ]; const sortedRoutes = sortRoutesBySidebar(route, sidebar); console.log(sortedRoutes); ``` ### 输出结果 ```javascript [ { path: '/', component: 'Home', title: '首页' }, { path: '/about', component: 'About', title: '关于我们' }, { path: '/contact', component: 'Contact', title: '联系我们' }, { path: '/products', component: 'Products', title: '产品' } ] ``` ### 关键点说明 - **映射优化查询**:通过 `Map` 结构将 `sidebar` 的 `title` 顺序转换为哈希表,时间复杂度为 `O(1)`。 - **稳定排序**:不在 `sidebar` 中的元素会保留原顺序并置于末尾。 - **兼容性**:假设 `title` 在 `sidebar` 中唯一,若存在重复需额外处理。 此方法确保 `route` 严格按 `sidebar` 的顺序排列,同时灵活处理
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值