Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/401.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何根据每个项目的特定键值对在对象数组中分离相似或相似的项目?_Javascript_Arrays_Sorting - Fatal编程技术网

Javascript 如何根据每个项目的特定键值对在对象数组中分离相似或相似的项目?

Javascript 如何根据每个项目的特定键值对在对象数组中分离相似或相似的项目?,javascript,arrays,sorting,Javascript,Arrays,Sorting,我得到了一个对象数组。数组中的每个对象都有一个键PlanType。。。我需要确保没有具有相同PlanType的对象彼此相邻 即使有时无法完全分离类似项,我如何实现这一点 [{Item:1,PlanType:A}, {项目:2,植物类型:B}, {项目:3,植物类型:C}, {项目:4,植物类型:C}, {项目:5,植物类型:A}, {项目:6,PlanType:A}, {项目:7,植物类型:B}, {项目:8,植物类型:A}, {项目:9,植物类型:C}, {Item:10,PlanType:

我得到了一个对象数组。数组中的每个对象都有一个键PlanType。。。我需要确保没有具有相同PlanType的对象彼此相邻

即使有时无法完全分离类似项,我如何实现这一点

[{Item:1,PlanType:A}, {项目:2,植物类型:B}, {项目:3,植物类型:C}, {项目:4,植物类型:C}, {项目:5,植物类型:A}, {项目:6,PlanType:A}, {项目:7,植物类型:B}, {项目:8,植物类型:A}, {项目:9,植物类型:C},
{Item:10,PlanType:A}]您可以这样做,这可能不是最有效的方法,但它可以帮助您解决问题

let A='A', B='B', C='C', D='D';
let f = [{ Item: 1, PlanType: A }, { Item: 2, PlanType: B }, { Item: 3, PlanType: C }, { Item: 4, PlanType: C }, { Item: 5, PlanType: A }, { Item: 6, PlanType: A }, { Item: 7, PlanType: B }, { Item: 8, PlanType: A }, { Item: 9, PlanType: C }, { Item: 10, PlanType: A } ];
let prevItem=f[0];
let currentItem;
for(let i=1; i<f.length; i++){
  currentItem = f[i];
  if(currentItem.PlanType === prevItem.PlanType){
    f.splice(i,1);
    f.push(currentItem);
    console.log("Item shifted");
  };
  prevItem = currentItem;
}
console.log(f);

我在解决算法方面很糟糕,但这就是我想到的。它还处理具有相同关键点的多个对象相继打开的情况

基本上,我已经从提供的数组中创建了另一个数组,我只是检查当前迭代中的项是否与新数组中的项相同。如果是,则将其添加到“堆栈”。当第一个条件失败时,它将继续将当前项插入新数组。完成后,我只是检查是否可以从该堆栈中获取一个项并将其插入新数组,然后将其从duplicateItems数组中删除

const items = [
  { Item: 1, PlanType: 'A' },
  { Item: 2, PlanType: 'B' },
  { Item: 3, PlanType: 'C' },
  { Item: 4, PlanType: 'C' },
  { Item: 5, PlanType: 'C' },
  { Item: 6, PlanType: 'A' },
  { Item: 7, PlanType: 'A' },
  { Item: 8, PlanType: 'B' },
  { Item: 9, PlanType: 'A' },
  { Item: 10, PlanType: 'C' },
  { Item: 11, PlanType: 'A' }
];

function normalizeList(items) {
  if (items.length < 1) return items;
  const result = [];
  const duplicateItems = [];
  items.forEach((item, index) => {
    if (result.length && item.PlanType === result[result.length - 1].PlanType) {
      if(index === items.length - 1) result.push(item); 
      else duplicateItems.push(item);
    }

    else {
      result.push(item);
      if(duplicateItems.length && duplicateItems[0].PlanType !== item.PlanType) {
        result.push(duplicateItems.shift());
      }
    }
  });
  return result;
}

在我看来,通过基本比较无法可靠地将价值相等或子财产价值相等的相邻项目相互转移。即将提出的方法不能称之为优雅的,因为它是基于直接数组变异和在很大程度上基于计数指数的。 它是为了在第一个迭代步骤中解决诸如

relocateEqualNeighboringItemValues(["A", "A", "B"]) => ["A", "B", "A"]
relocateEqualNeighboringItemValues(["A", "A", "B", "C", "C"]) => ["A", "C", "B", "A", "C"]
通过第二个迭代步骤,还可以传递一个getter,例如,对于更复杂结构的项,它确实以项的特定属性为目标

relocateEqualNeighboringItemValues([

  { item: 1, planType: "A" },
  { item: 2, planType: "A" },
  { item: 3, planType: "B" }

], (item => item.planType)) => [

  { item: 1, planType: "A" },
  { item: 3, planType: "B" },
  { item: 2, planType: "A" }
]
实现如下所示

函数relocateeQualNeighboringItemValuesR,getItemValue{ 如果Array.isArrayarr&&arr.length>=3{ 常量getValue= getItemValue的类型===“函数”&& item=>item&&getItemValueitem ||item=>item;//getter默认值。 让我们的位置=假; 让我们来讨论这个项目; 让抵销计算; 让项目计数; 让项目价值; 让leftToRightIndex; 设rightToLeftIndex=arr.length; 而!isTerminateRelocation&-rightToLeftIndex>=0{ isRelocateItem=false; itemValue=getValuearr[rightToLeftIndex]; //-针对每个项目从右到左重复练习重新定位查找, //如果可能,尝试重新定位这样一个相等的相邻项值。 如果itemValue===getValuearr[rightToLeftIndex-1]{ 抵销数=1; isRelocateItem=true; 而isRelocateItem&&rightToLeftIndex-++offsetCount>=0{ 如果 itemValue!==getValuearr[rightToLeftIndex-offsetCount]&& itemValue!==getValuearr[rightToLeftIndex-offsetCount-1] { arr.stipleRightToLeftIndex-偏移计数,0,arr.stipleRightToLeftIndex,1[0]; ++rightToLeftIndex;//重置…从前一个输入位置开始查找。 isRelocateItem=false; } } //-如果特定项目的从右到左重新定位卡在阵列边界上, //将此项目的查找方向从左到右专门更改,然后尝试重新定位它。 //-如果重新定位尝试再次失败,则无法执行任何操作。该过程将终止。 如果isRelocateItem&&rightToLeftIndex-offsetCount<0{ 抵销数=1; itemCount=arr.length; leftToRightIndex=Math.max0,rightToLeftIndex-1; itemValue=getValuearr[leftToRightIndex]; isRelocateItem=itemValue==getValuearr[leftToRightIndex+1]; 而isRelocateItem&&leftToRightIndex+++offsetCount=itemCount{ ISTERMINATERLOCATION=true; } } } } } 返回arr; } 测试用例

基本的


函数重新定位QualNeighboringItemValueSA,b{ifArray.isArraya&&3a&&ba | | a=>a;让d,e,f,g,h,i=!1,j=a.length;for;!i&&0请访问查看和。提示:发布工作和代码。我为您制作了一个代码段。请将您尝试的代码添加到其中,并解释哪些代码不起作用,以及有时无法完全分离它们的示例。是否要筛选arrayremove重复输入?或返回真/假
?您可以使用每个语句。在一个键中分配当前对象,并与下一个即将到来的对象进行比较。至少,您可以提供给定输入的预期输出。提供的测试示例记录一个PlanType:“a”序列。。。索引3中的第5项后接索引4中的第6项。使用此方法测试某些边缘情况。。。1 var items=[{Item:0,PlanType:'A'},{Item:1,PlanType:'A'},{Item:2,PlanType:'B'}]将被很好地排序。。。2 var items=[{Item:0,PlanType:'A'},{Item:1,PlanType:'B'},{Item:2,PlanType:'B'}]在排序过程中以某种方式松开了{Item:2,PlanType:'B'}。你说得对,@PeterSeliger。在您提供的第二种情况下,函数将看到该项与之前的项具有相同的PlanType,并且它将仅将其插入到duplicateItems列表中,而不应将其插入到结果列表中。谢谢你指出这一点。我已经编辑了我的答案。我是怎么说的,我在解决算法方面很糟糕。解决OP的问题可能需要另一种方法。。。例如,您的代码的最后版本没有通过以下结构的测试。。。1[{Item:1,PlanType:'A'},{Item:2,PlanType:'B'},{Item:3,PlanType:'C'},{Item:4,PlanType:'C'}]。。。2[{Item:1,PlanType:'A'},{Item:2,PlanType:'B'},{Item:3,PlanType:'B'},{Item:4,PlanType:'B'},{Item:5,PlanType:'C'}]。