- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
TL; 博士;
为简单起见,我如何过滤父子数组的多个属性,这些属性可能是几个树级别的深度。这是针对数百个用户使用的开源数据网格库。
所以我有一系列父/子引用, children 也可以有 child 自己等等,树级深度没有限制。此外,我不仅需要能够过滤具有树结构的属性,还需要能够过滤该数组的任何属性,即网格中的列。
例如,我有这个数组,它代表一个文件浏览器列表
const myFiles = [
{id: 11, file: "Music", parentId: null },
{id: 12, file: "mp3", parentId: 11 },
{id: 14, file: "pop", parentId: 12 },
{id: 15, file: "theme.mp3", dateModified: "2015-03-01", size: 85, parentId: 14, },
{id: 16, file: "rock", parentId: 12 },
{id: 17, file: "soft.mp3", dateModified: "2015-05-13", size: 98, parentId: 16, },
{id: 18, file: "else.txt", dateModified: "2015-03-03", size: 90, parentId: null, },
{id: 21, file: "Documents", parentId: null, },
{id: 2, file: "txt", parentId: 21 },
{id: 3, file: "todo.txt", dateModified: "2015-05-12", size: 0.7, parentId: 2, },
{id: 4, file: "pdf", parentId: 21 },
{id: 22, file: "map2.pdf", dateModified: "2015-05-21", size: 2.9, parentId: 4 },
{id: 5, file: "map.pdf", dateModified: "2015-05-21", size: 3.1, parentId: 4, },
{id: 6, file: "internet-bill.pdf", dateModified: "2015-05-12", size: 1.4, parentId: 4, },
{id: 7, file: "xls", parentId: 21 },
{id: 8, file: "compilation.xls", dateModified: "2014-10-02", size: 2.3, parentId: 7, },
{id: 9, file: "misc", parentId: 21 },
{id: 10, file: "something.txt", dateModified: "2015-02-26", size: 0.4, parentId: 9, },
]
{id: 21, file: "Documents", parentId: null, treeMap: ["Documents", "PDF", "map.pdf"] }
{id: 4, file: "pdf", parentId: 21, treeMap: ["PDF", "map.pdf"] }
{id: 5, file: "map.pdf", dateModified: "2015-05-21", size: 3.1, parentId: 4, treeMap: ["map.pdf"] }
export function modifyDatasetToAddTreeMapping(items: any[], treeViewColumn: Column, dataView: any) {
for (let i = 0; i < items.length; i++) {
items[i]['treeMap'] = [items[i][treeViewColumn.id]];
let item = items[i];
if (item['parentId'] !== null) {
let parent = dataView.getItemById(item['parentId']);
while (parent) {
parent['treeMap'] = dedupePrimitiveArray(parent['treeMap'].concat(item['treeMap']));
item = parent;
parent = dataView.getItemById(item['parentId']);
}
}
}
}
export function dedupePrimitiveArray(inputArray: Array<number | string>): Array<number | string> {
const seen = {};
const out = [];
const len = inputArray.length;
let j = 0;
for (let i = 0; i < len; i++) {
const item = inputArray[i];
if (seen[item] !== 1) {
seen[item] = 1;
out[j++] = item;
}
}
return out;
}
columnFilters
是一个包含 1 个或多个过滤器的对象,例如
const columnFilters = { file: 'map', size: '>3' }
dataView.setFilter(treeFilter);
function treeFilter(dataView: any, item: any) {
const columnFilters = { file: this.searchString.toLowerCase(), size: 2 };
let filterCount = 0;
if (item[parentPropName] !== null) {
let parent = dataView.getItemById(item['parentId']);
while (parent) {
if (parent.__collapsed) {
return false;
}
parent = dataView.getItemById(parent['parentId']);
}
}
for (const columnId in columnFilters) {
if (columnId !== undefined && columnFilters[columnId] !== '') {
filterCount++;
if (item.treeMap === undefined || !item.treeMap.find((itm: string) => itm.endsWith(columnFilters[columnId]))) {
return false;
}
}
}
return true;
}
modifyDatasetToAddTreeMapping()
的电话如果我想在 File 列上过滤它可以正常工作,但是如果我添加更多列过滤器,它就不能按预期工作。例如,如果您查看第二个打印屏幕,您会看到我输入了“map”,它将显示“Documents > PDF > map.pdf”,这很好,但是如果添加的文件大小小于 3Mb,则应该't 显示“map.pdf”,并且因为该文件未显示并且“文档> PDF”不包含“ map ”一词,因此不应显示任何内容,因此您可以看到过滤器的行为不正常。
modifyDatasetToAddTreeMapping()
是一个可能不需要的额外调用
filter
,这意味着最终的解决方案将是一种方法
myFilter
那将是
filter
回调方法。我坚持这个的原因是因为我使用了一个外部库
SlickGrid并且我必须使用该库中可用的内容作为公开的公共(public)方法。
function myFilter(item, args) {
const columnFilters = args.columnFilters;
// iterate through each items of the dataset
// return true/false on each item
}
// to be used as a drop in
dataView.setFilterArgs({ columnFilters: this._columnFilters });
dataView.setFilter(myFilter.bind(this));
const columnFilters = { file: "map", size: "<3.2" };
,数组的预期结果将是 4 行
// result
[
{id: 21, file: "Documents", parentId: null },
{id: 4, file: "pdf", parentId: 21, },
{id: 22, file: "map2.pdf", dateModified: "2015-05-21", size: 2.9, parentId: 4 },
{id: 5, file: "map.pdf", dateModified: "2015-05-21", size: 3.1, parentId: 4, }
]
const columnFilters = { file: "map", size: "<3" };
,数组的预期结果将是 3 行
// result
[
{id: 21, file: "Documents", parentId: null },
{id: 4, file: "pdf", parentId: 21, },
{id: 22, file: "map2.pdf", dateModified: "2015-05-21", size: 2.9, parentId: 4 },
]
const columnFilters = { file: "map", size: ">3" };
那么预期的结果将是一个空数组,因为没有一个文件具有该字符和文件大小条件。
最佳答案
我有办法做到这一点。它应该具有相当的性能,但我们可能还想将 map 和 reduce 等替换为旧的 for 循环以进一步优化速度(我看过各种博客和文章,比较了 forEach、map 等与 for 循环和 for 的速度) -循环似乎赢了)
这是一个演示(也在这里: https://codepen.io/Alexander9111/pen/abvojzN ):
const myFiles = [
{ id: 11, file: "Music", parentId: null },
{ id: 12, file: "mp3", parentId: 11 },
{ id: 14, file: "pop", parentId: 12 },
{ id: 15, file: "theme.mp3", dateModified: "2015-03-01", size: 85, parentId: 14 },
{ id: 16, file: "rock", parentId: 12 },
{ id: 17, file: "soft.mp3", dateModified: "2015-05-13", size: 98, parentId: 16 },
{ id: 18, file: "else.txt", dateModified: "2015-03-03", size: 90, parentId: null },
{ id: 21, file: "Documents", parentId: null },
{ id: 2, file: "txt", parentId: 21 },
{ id: 3, file: "todo.txt", dateModified: "2015-05-12", size: 0.7, parentId: 2 },
{ id: 4, file: "pdf", parentId: 21 },
{ id: 22, file: "map2.pdf", dateModified: "2015-05-21", size: 2.9, parentId: 4 },
{ id: 5, file: "map.pdf", dateModified: "2015-05-21", size: 3.1, parentId: 4 },
{ id: 6, file: "internet-bill.pdf", dateModified: "2015-05-12", size: 1.4, parentId: 4 },
{ id: 7, file: "xls", parentId: 21 },
{ id: 8, file: "compilation.xls", dateModified: "2014-10-02", size: 2.3, parentId: 7 },
{ id: 9, file: "misc", parentId: 21 },
{ id: 10, file: "something.txt", dateModified: "2015-02-26", size: 0.4, parentId: 9 }
];
//example how to use the "<3" string - better way than using eval():
const columnFilters = { file: "map", size: "<3.2" }; //, size: "<3"
const isSizeValid = Function("return " + myFiles[11].size + "<3")();
//console.log(isSizeValid);
const myObj = myFiles.reduce((aggObj, child) => {
aggObj[child.id] = child;
//the filtered data is used again as each subsequent letter is typed
//we need to delete the ._used property, otherwise the logic below
//in the while loop (which checks for parents) doesn't work:
delete aggObj[child.id]._used;
return aggObj;
}, {});
function filterMyFiles(myArray, columnFilters){
const filteredChildren = myArray.filter(a => {
for (let key in columnFilters){
//console.log(key)
if (a.hasOwnProperty(key)){
const strContains = String(a[key]).includes(columnFilters[key]);
const re = /(?:(?:^|[-+<>=_*/])(?:\s*-?\d+(\.\d+)?(?:[eE][+-<>=]?\d+)?\s*))+$/;
const comparison = re.test(columnFilters[key]) && Function("return " + a[key] + columnFilters[key])();
if (strContains || comparison){
//don't return true as need to check other keys in columnFilters
}else{
//console.log('false', a)
return false;
}
} else{
return false;
}
}
//console.log('true', a)
return true;
})
return filteredChildren;
}
const initFiltered = filterMyFiles(myFiles, columnFilters);
const finalWithParents = initFiltered.map(child => {
const childWithParents = [child];
let parent = myObj[child.parentId];
while (parent){
//console.log('parent', parent)
parent._used || childWithParents.unshift(parent)
myObj[parent.id]._used = true;
parent = myObj[parent.parentId] || false;
}
return childWithParents;
}).flat();
console.log(finalWithParents)
.as-console-wrapper { max-height: 100% !important; top: 0; }
const myFiles = [
{ id: 11, file: "Music", parentId: null },
{ id: 12, file: "mp3", parentId: 11 },
{ id: 14, file: "pop", parentId: 12 },
{ id: 15, file: "theme.mp3", dateModified: "2015-03-01", size: 85, parentId: 14 },
{ id: 16, file: "rock", parentId: 12 },
{ id: 17, file: "soft.mp3", dateModified: "2015-05-13", size: 98, parentId: 16 },
{ id: 18, file: "else.txt", dateModified: "2015-03-03", size: 90, parentId: null },
{ id: 21, file: "Documents", parentId: null },
{ id: 2, file: "txt", parentId: 21 },
{ id: 3, file: "todo.txt", dateModified: "2015-05-12", size: 0.7, parentId: 2 },
{ id: 4, file: "pdf", parentId: 21 },
{ id: 22, file: "map2.pdf", dateModified: "2015-05-21", size: 2.9, parentId: 4 },
{ id: 5, file: "map.pdf", dateModified: "2015-05-21", size: 3.1, parentId: 4 },
{ id: 6, file: "internet-bill.pdf", dateModified: "2015-05-12", size: 1.4, parentId: 4 },
{ id: 7, file: "xls", parentId: 21 },
{ id: 8, file: "compilation.xls", dateModified: "2014-10-02", size: 2.3, parentId: 7 },
{ id: 9, file: "misc", parentId: 21 },
{ id: 10, file: "something.txt", dateModified: "2015-02-26", size: 0.4, parentId: 9 }
];
const columnFilters = { file: "map", size: "<3.2" };
console.log(customLocalFilter(myFiles, columnFilters));
function customLocalFilter(array, filters){
const myObj = {};
for (let i = 0; i < myFiles.length; i++) {
myObj[myFiles[i].id] = myFiles[i];
//the filtered data is used again as each subsequent letter is typed
//we need to delete the ._used property, otherwise the logic below
//in the while loop (which checks for parents) doesn't work:
delete myObj[myFiles[i].id]._used;
}
const filteredChildrenAndParents = [];
for (let i = 0; i < myFiles.length; i++) {
const a = myFiles[i];
let matchFilter = true;
for (let key in columnFilters) {
if (a.hasOwnProperty(key)) {
const strContains = String(a[key]).includes(columnFilters[key]);
const re = /(?:(?:^|[-+<>!=_*/])(?:\s*-?\d+(\.\d+)?(?:[eE][+-<>!=]?\d+)?\s*))+$/;
const comparison =
re.test(columnFilters[key]) &&
Function("return " + a[key] + columnFilters[key])();
if (strContains || comparison) {
//don't return true as need to check other keys in columnFilters
} else {
matchFilter = false;
continue;
}
} else {
matchFilter = false;
continue;
}
}
if (matchFilter) {
const len = filteredChildrenAndParents.length;
filteredChildrenAndParents.splice(len, 0, a);
let parent = myObj[a.parentId] || false;
while (parent) {
//only add parent if not already added:
parent._used || filteredChildrenAndParents.splice(len, 0, parent);
//mark each parent as used so not used again:
myObj[parent.id]._used = true;
//try to find parent of the current parent, if exists:
parent = myObj[parent.parentId] || false;
}
}
}
return filteredChildrenAndParents;
}
.as-console-wrapper { max-height: 100% !important; top: 0; }
关于javascript - 如何过滤可能是几个树级别深度的父子数组的多个属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61034229/
我正在使用python 2.7 当我尝试在其上运行epsilon操作时出现此错误, 这是我的代码 import cv2 import numpy as np img = cv2.imread('img
1 很多程序员对互联网行业中广泛讨论的“35岁危机”表示不满,似乎所有的程序员都有着35岁的职业保质期。然而,随着AI技术的兴起,这场翻天覆地的技术革命正以更加残酷且直接的方式渗透到各行各业。程序员
我有一个包含多个子模块的项目,我想列出每个子模块的相对深度 该项目: main_project submodule1 submodule1\submodule1_1 submo
我有一张彩色图像及其深度图,它们都是由 Kinect 捕获的。我想将它投影到另一个位置(以查看它在另一个视角下的样子)。由于我没有 Kinect 的内在参数(相机参数);我该如何实现? P.S:我正在
给出了这三个网址: 1) https://example.com 2) https://example.com/app 3) https://example.com/app?param=hello 假
这个着色器(最后的代码)使用 raymarching 来渲染程序几何: 但是,在图像(上图)中,背景中的立方体应该部分遮挡粉红色实体;不是因为这个: struct fragmentOutput {
我希望能够在 ThreeJS 中创建一个房间。这是我到目前为止所拥有的: http://jsfiddle.net/7oyq4yqz/ var camera, scene, renderer, geom
我正在尝试通过编写小程序来学习 Haskell...所以我目前正在为简单表达式编写一个词法分析器/解析器。 (是的,我可以使用 Alex/Happy...但我想先学习核心语言)。 我的解析器本质上是一
我想使用像 [parse_ini_file][1] 这样的东西。 例如,我有一个 boot.ini 文件,我将加载该文件以进行进一步的处理: ;database connection sett
我正在使用 Mockito 来测试我的类(class)。我正在尝试使用深度 stub ,因为我没有办法在 Mockito 中的另一个模拟对象中注入(inject) Mock。 class MyServ
我试图在调整设备屏幕大小时重新排列布局,所以我这样做: if(screenOrientation == SCREEN_ORIENTATION_LANDSCAPE) { document
我正在 Ubuntu 上编写一个简单的 OpenGL 程序,它使用顶点数组绘制两个正方形(一个在另一个前面)。由于某种原因,GL_DEPTH_TEST 似乎不起作用。后面的物体出现在前面的物体前面
static FAST_FUNC int fileAction(const char *pathname, struct stat *sb UNUSED_PARAM, void *mo
我有这样的层次结构: namespace MyService{ class IBase { public: virtual ~IBase(){} protected: IPointer
我正在制作一个图片库,需要一些循环类别方面的帮助。下一个深度是图库配置文件中的已知设置,因此这不是关于无限深度循环的问题,而是循环已知深度并输出所有结果的最有效方法。 本质上,我想创建一个 包含系统中
如何以编程方式在树状结构上获取 n 深度迭代器?在根目录中我有 List 每个节点有 Map> n+1 深度。 我已修复 1 个深度: // DEPTH 1 nodeData.forEach(base
我正在构建一个包含大量自定义元素的 Polymer 单页界面。 现在我希望我的元素具有某种主样式,我可以在 index.html 或我的主要内容元素中定义它。可以这样想: index.html
我正在尝试每 25 秒连接到配对的蓝牙设备,通过 AlarmManager 安排,它会触发 WakefulBroadcastReceiver 以启动服务以进行连接。设备进入休眠状态后,前几个小时一切正
假设有一个有默认值的函数: int foo(int x=42); 如果这被其他人这样调用: int bar(int x=42) { return foo(x); } int moo(int x=42)
是否可以使用 Javascript 获取 url 深度(级别)? 如果我有这个网址:www.website.com/site/product/category/item -> depth=4www.w
我是一名优秀的程序员,十分优秀!