Dataviewjs的奇技淫巧

太怪了,我导出得很完美啊

经测试,跟库的笔记数量有关。
换到小库时,我自用的代码、您提供的第2版,都能正常导出pdf、html

捂脸

let files = dv.pages().filter(p=>p.菜名)
console.log(files)
let d=[]
for(let p of files) {
	p.file.link.display=p.菜名
	d.push({link:p.file.link,name:p.菜名,非常喜欢:p?.非常喜欢,不喜欢:p?.不喜欢})
}
let target = '陈大'
dv.header(2,target+'饮食喜好表')
dv.table(
	['程度','菜名'],
	[['非常喜欢',d.map(p=>{if(p.非常喜欢?.split('、').includes(target)) return p.link}).filter(p=>p).join('、')],
	 ['不喜欢',d.map(p=>{if(p.不喜欢?.split('、').includes(target)) return p.link}).filter(p=>p).join('、')]]
)

@lazyloong 大佬,针对上述代码, 下面这个疑问能帮忙解答一下不?
yaml值如下:

非常喜欢: 小明随机内容A、小华随机内容B
不喜欢: 大柱子随机内容C

也就是在名字后面,还有随机内容,请问应该怎样修改代码,才能识别内容并提取汇总呢?

你这个需求我有点理解不了,随机内容放在表格中的哪呢,这里面需要寻找的是菜名而不是人名啊,要加内容不应该是菜名后加内容吗

随机内容有可能跟在 菜名 后面吗?

- 分割

```dataviewjs
let target = '陈大'
dv.header(2,target+'饮食喜好表')
dv.table(
	['程度','菜名'],
	fun(target,['非常喜欢','不喜欢'],'菜名')
)

function fun(target,yamls,yaml) {
	let files = dv.pages().filter(p=>p[yaml])
	let d=[]
	for(let p of files) {
		p.file.link.display = p[yaml]
		d.push({link:p.file.link,
				 name:p[yaml],
				 ...Object.fromEntries(yamls.map(y=>[y,p[y]?p[y].split('-'):undefined]))})
	}
	return yamls.map(y=>[y,d.map(p=>{if(p[y]?.[0]?.split('、').includes(target)) return function(link){console.log(link);link.display=`${link.display}(${p[y][1]})`;return link}(p.link)}).filter(p=>p).join('、')])
}
```

也是研究video后辈同行啊,想当年还是mendeley和evernote结合

是我想要的效果,太赞了,谢谢!

@lazyloong 请教一下,dvjs可以获取并列出 具有相同/相似名称的笔记吗?谢谢

当然可以,前提是你能用代码语言精确地定义什么叫相似

不会编程,请问有类似的样例可以参考下么?例如前10个字符相同,就判定为相似

@lazyloong 我手上有一个代码,作用是:获取与当前笔记名相似的笔记。使用正常,但按相似度降序排列,一直不生效,能否请大神 帮忙修正一下?谢谢

// 定义一个函数来计算两个字符串的Dice的系数,和之前的一样
function diceCoefficient(str1, str2) {
  // 如果两个字符串完全相同,返回1
  if (str1 === str2) return 1;
  // 如果两个字符串长度小于2,返回0
  if (str1.length < 2 || str2.length < 2) return 0;
  // 将字符串转换为小写
  str1 = str1.toLowerCase();
  str2 = str2.toLowerCase();
  // 定义一个集合来存储两个字符串的双字母组合
  let pairs1 = new Set();
  let pairs2 = new Set();
  // 遍历两个字符串,将双字母组合加入集合
  for (let i = 0; i < str1.length - 1; i++) {
    pairs1.add(str1.slice(i, i + 2));
  }
  for (let i = 0; i < str2.length - 1; i++) {
    pairs2.add(str2.slice(i, i + 2));
  }
  // 定义一个变量来存储两个集合的交集的大小
  let intersection = 0;
  // 遍历一个集合,判断另一个集合是否包含相同的元素,如果是,交集大小加一
  for (let pair of pairs1) {
    if (pairs2.has(pair)) intersection++;
  }
  // 返回Dice的系数,即交集大小除以集合大小之和的一半
  return (2 * intersection) / (pairs1.size + pairs2.size);
}

// 在dataviewjs代码块中调用这个函数,比较所有笔记名称和当前笔记名称的相似度,如果大于0.45,就呈现一个表格,表格的每一行是一个笔记的名称和相似度,然后按照相似度降序排列
dv.table(
  ["与当前文件名相似的笔记", "相似度"],
  dv.pages()
    .where((p) => p.file.name !== dv.current().file.name && diceCoefficient(p.file.name, dv.current().file.name) > 0.45) // 排除当前笔记的名称
	.map((p) => [
      p.file.link,
      diceCoefficient(p.file.name, dv.current().file.name).toFixed(2),
      ])
    .sort((a, b) => parseFloat(b[1]) - parseFloat(a[1])) // 将字符串转换为数字,然后按照相似度降序排列
    .limit(15) // 限制结果数量为15条
);
1 个赞

因为dataview相关函数返回的不是原生数组,而是它自己的数组类


```dataviewjs
// 定义一个函数来计算两个字符串的Dice的系数,和之前的一样
function diceCoefficient(str1, str2) {
  // 如果两个字符串完全相同,返回1
  if (str1 === str2) return 1;
  // 如果两个字符串长度小于2,返回0
  if (str1.length < 2 || str2.length < 2) return 0;
  // 将字符串转换为小写
  str1 = str1.toLowerCase();
  str2 = str2.toLowerCase();
  // 定义一个集合来存储两个字符串的双字母组合
  let pairs1 = new Set();
  let pairs2 = new Set();
  // 遍历两个字符串,将双字母组合加入集合
  for (let i = 0; i < str1.length - 1; i++) {
    pairs1.add(str1.slice(i, i + 2));
  }
  for (let i = 0; i < str2.length - 1; i++) {
    pairs2.add(str2.slice(i, i + 2));
  }
  // 定义一个变量来存储两个集合的交集的大小
  let intersection = 0;
  // 遍历一个集合,判断另一个集合是否包含相同的元素,如果是,交集大小加一
  for (let pair of pairs1) {
    if (pairs2.has(pair)) intersection++;
  }
  // 返回Dice的系数,即交集大小除以集合大小之和的一半
  return (2 * intersection) / (pairs1.size + pairs2.size);
}

// 在dataviewjs代码块中调用这个函数,比较所有笔记名称和当前笔记名称的相似度,如果大于0.45,就呈现一个表格,表格的每一行是一个笔记的名称和相似度,然后按照相似度降序排列
dv.table(
  ["与当前文件名相似的笔记", "相似度"],
  dv.pages()
    .where((p) => p.file.name !== dv.current().file.name && diceCoefficient(p.file.name, dv.current().file.name) > 0.45) // 排除当前笔记的名称
	.map((p) => [
      p.file.link,
      diceCoefficient(p.file.name, dv.current().file.name).toFixed(2),
      ])
    .sort((a) => - parseFloat(a[1])) // 将字符串转换为数字,然后按照相似度降序排列
    .limit(15) // 限制结果数量为15条
);
```

十分感谢,修改后可以排序了!

@lazyloong 大佬,再请教一个问题, dataview可以获取访问次数最少或最多的前50条笔记吗?找了一下,没看到相关参数

那应该不行,至少我没有见过什么地方记录了访问次数,没有数据自然不能获取,除非你自己在yaml区记录次数,并且做好维护

明白了,谢谢解答

lz太强了,爬完了所有楼,非常值得学习,但是最近有个需求常常困惑我,就是dataviewjs进行查询后,返回的结果中不会进行渲染图片,或者不会渲染从其他文件中,基于block引用的内容,如![[File#^78gula]]——不会显示这个引用的内容,只会显示名字“File#^78gula”请问lz在使用过程中有遇到这种问题吗?

翻阅了github上等等内容,没有找到解决方案,但是总觉得应该是可以的,如像dv.paragraph(await dv.io.load(“File.md”))是可以实现渲染整个页面的。想请教lz关于这个有没有什么解决方案?

以前有过这样的情况,但是刚才测试的时候发现正常了,我这能正常显示了,比如这样

dv.paragraph(`![[离散随机变量-概率分布#^n70lba]]`)