过滤和搜索满足复杂条件的对象/数组项

时间:2017-02-27 14:59:56

标签: javascript arrays json javascript-objects

如何在JSON / JavaScript数组或对象中找到符合逻辑条件的项目(或其父值)?

我正在尝试(定义magicalWay函数!):

myArray = [
            {"type":"A","items":[0,1,2,3,4]},
            {"type":"B","items":['x','y','z']}
          ];

magicalWay(myArray,"<parent>.type=='A'","<this>.items");
//and output: [0,1,2,3,4]

magicalWay(myArray,"true","<this>.items");
//and output: [[0,1,2,3,4],['x','y','z']]

myObject = {
  "type": "A",
  "items": [
    {
      "type": "B",
      "items": ['x','y']
    },
    {
      "type": "C",
      "items": [0,1]
    }
  ]
};

magicalWay(myObject,"true","<this>.items[*].items");
//and output: [['x','y'],[0,1]]

任何建议都有助于我:)

我认为我的magicalWay函数必须使用array.prototype.filter一些方法:

function magicalWay(myVar,strCondition,strPattern){
  //replacing strCondition groups like [*] and others, and evaluate strCondition for each searching items.
  //strPattern is which path should be extract and search
  //and myVar is which searching through!
}

附加:就像MySQL JSON提取一样,&#39; $ [*]。items&#39;在一个数组中返回所有项目的items值!

1 个答案:

答案 0 :(得分:2)

第一步是定义您用来获得所需结果的实际函数

var myArray = [
  {
    "type": "A",
    "items": [0, 1, 2, 3, 4]
  },
  {
    "type": "B",
    "items": ['x', 'y', 'z']
  }
];

var result1 = myArray
  .filter(obj => obj.type === "A")            // Select
  .map(obj => obj.items)                      // Get nested
  .reduce((arr, cur) => arr.concat(cur), []); // Flatten

//[0,1,2,3,4]
console.log(JSON.stringify(result1));

您需要为object输入执行相同的操作。在您了解filtermapreduce的工作原理后,您可以使用此签名创建一个函数:

function getData(source, itemFilter, propertyGetter) { /* ... */ }

现在,如果要求从基于字符串的过滤器定义开始,则必须解析字符串并返回实际函数。我认为你提出的字符串逻辑有点危险并且难以解析,但是如果你编写严格的测试,你可能会侥幸逃脱......起点可能是:

const noFilter = () => true;

function getFilterMethod(str) {
  if (str === "true") {
    return noFilter;
  }
  
  const parts = str.split(".").slice(1);
  
  return (
    obj => parts.reduce((cur, key) => cur[key], obj)
  );
}

const data = [
  { items: true },
  { items: false },
  { test: 1 }
];

console.log("true:",
  JSON.stringify(data.filter(getFilterMethod("true")))
);


console.log("<this>.items:",
  JSON.stringify(data.filter(getFilterMethod("<this>.items")))
);

将两者结合起来,添加数据获取逻辑,然后你就会走向:

magicalWay(
  myArray, getFilterMethod("true"), getPropertyExtractor("<this>.items")
)

我不会为你编写其余的代码,但如果你有特定的问题,我很乐意提供帮助!