按顺序按键过滤json对象

时间:2018-06-22 22:14:55

标签: javascript json

我正在尝试根据用户输入通过键过滤嵌套的json对象,但是键的数量可以完全动态。我还需要根据索引/深度进行搜索。

例如,如果您使用此json:

values = {
  1: {
    4: {
      9: {
         ...
      },
      10: {
         ...
      }
    },
    7: {
      12: {
         ...
      },
      15: {
         ...
      },
      18: {
         ...
      }
    }
  },
  2: {
    5: {
      7: {
         ...
      }
    }
  }
}

我想要以下结果:

search = [1]

result:
{
  1: {
    4: {
      9: {
         ...
      },
      10: {
         ...
      }
    },
    7: {
      12: {
         ...
      }
      15: {
         ...
      }
      18: {
         ...
      }
    }
  }
}

search = [1, 4]

result:
{   
    4: {
        9: {
          ...
        },
        10: {
          ...
        }
    }
}


search = [1, 4, 9]

result:

{ 
  9: {
      ...
  }
}


search = [2, 5]

result:
{   
    5: {
       7: {
          ...
       }
    }
}

起初我以为我可以去result = values[2][5],但是由于键和json在内容和深度上都是完全动态的,因此无法正常工作。

我尝试使用过滤器,但是它只能在一个级别上使用,因为我需要先知道X个先前的键。

有人有什么想法吗?

编辑

这被标记为这篇文章Search key in nested complex JSON的重复,但这与我没有在整个对象中搜索该键的第一个结果并不完全相同。键并不总是唯一的,例如它们可能在整个对象中的其他位置,因此我需要按顺序遍历对象。

1 个答案:

答案 0 :(得分:0)

使用JSON,您仍然可以使用数组。如果要按索引选择,则必须像这样编写JSON。

[
  [
    { 'key' : 'value' },
    { 'key' : 'value' }
  ],
  [
    { 'key' : 'value' },
    { 'key' : 'value' }
  ]
],
[ ... ],
[ ... ]

假设您的JavaScript然后将此JSON分配给了const values,那么您将能够使用语法values[0][1]访问这些对象中的任何一个。这样,您无需做任何其他工作即可使索引动态化,因为这是它们的标准行为。

就动态深度而言,您可以使用方便的Array.prototype.every()编写一个简短函数。

const search = (searchArr, idxArr) => {
  let result = searchArr
  const exists = () => idxArr.every(idx => result = result[idx])
  return exists() ? result : null
}

或ES5,如果您愿意:

var search = function(searchArr, idxArr) {
  var result = searchArr;
  var exists = function() {
    return idxArr.every(function (idx) {
      return result = result[idx];
    });
  };
  return exists() ? result : null;
};

codepen上查看示例。