【问题标题】:ValueIterator.toArray().indexOf() returns unexpected results?ValueIterator.toArray().indexOf() 返回意外结果?
【发布时间】:2015-12-17 14:08:11
【问题描述】:

更新:这不仅仅是关于 javascript 的问题,而是与 MarkLogic 平台上的 javascript 实现有关。 正如这个问题的标题所指出的,它与 ValueIterator 函数返回的 xdmp.userRoles() 的具体行为有关。

我正在尝试查看用户是否在 MarkLogic 安全数据库中具有特定角色,因此我已经这样做了:

declareUpdate();

var pid = '7610802';

// TODO validate that user can do this
var spo  = 'scc-proj-' + pid + '-owner';
var spm  = 'scc-proj-' + pid + '-member';
var spam = 'scc-proj-' + pid + '-adv-member';
// we need the security db Ids of these roles
var spoId = xdmp.role(spo);
var spamId = xdmp.role(spam);
var acceptedRoleIds = [spamId,spoId];

// get roleIds from sec db for this user
var userRoleIds = xdmp.userRoles('scc-user-1');
// map ValueIterator to array
var userRoleIdsArray = userRoleIds.toArray(); 

现在 userRoleIdsArray 将 id 保存为 unnsigned long ,如下所示:

[
"1088529792688125909", 
"1452323661308702627", 
"10258509559147330558", 
"10161853410412530308", 
"6677433310138437512", 
"12773061729023600875", 
"7482704131174481508", 
"3191093315651213021", <<<<< this is the one!!!
"5126952842460325403", 
"7089338530631756591", 
"15520654661378671735", 
"13041542794130379697"
]

现在 indexOf() 给我-1 aka not found

userRoleIdsArray.indexOf(3191093315651213021);

userRoleIdsArray.indexOf("3191093315651213021");

给:

-1

虽然

userRoleIdsArray[7]==3191093315651213021;

给:

true

我在这里缺少什么?这不是indexOf()的使用方式吗?

更新 >>> 下面的东西是“在一边”,但结果却分散了上述核心问题的注意力。 @DaveCassel 的评论回答了以下行为。

btw 在创建的数组acceptedRoleIds 上更奇怪:

acceptedRoleIds.indexOf(spoId);

作品

acceptedRoleIds.indexOf(3191093315651213021);

没有?

this large number error in javascript 是否相关?

【问题讨论】:

  • 嗯,在浏览器控制台输入3191093315651213021,回车就可以看到了。
  • 试过 userRoleIdsArray.indexOf("3191093315651213021"); ?
  • 也就是说,如果 id 是字符串,为什么要尝试使用整数来访问它们?
  • @Idos 恐怕这个问题比你意识到的更复杂,这不是一个普通的 javascript 问题......你的回答不能解决我的问题......你的代码工作正常。但是我的问题是,如果我将 ValueIterator(我相信它是特定于 ML 的)转换为数组并在 MarkLogic 中使用 indexOf() 函数,则会遇到上述问题。

标签: javascript marklogic


【解决方案1】:

您想查找String,而不是数字。使用:userRoleIdsArray.indexOf("3191093315651213021");

这行得通:

var array = [
"1088529792688125909", 
"1452323661308702627", 
"10258509559147330558", 
"10161853410412530308", 
"6677433310138437512", 
"12773061729023600875", 
"7482704131174481508", 
"3191093315651213021",
"5126952842460325403", 
"7089338530631756591", 
"15520654661378671735", 
"13041542794130379697"
];
var n = array.indexOf("13041542794130379697");
document.write(n);

output: 11

【讨论】:

  • @HugoKoopmans - MarkLogic 是什么无关紧要 - 字符串中的字符串和 int 是 int。在构建数组时,您正在构建一个字符串数组(它们周围有引号)。当您查询索引时,您是在请求数组中具有该值的 int 的索引。您的数组中没有整数值,因此它返回 -1。
  • 补充说明 - MarkLogic 是一个 NoSQL 数据库。您正在建立什么样的数据库连接与 .js 代码本身无关。您询问的部分不是数据库的一部分,而是 javascript 的一部分。
  • @HugoKoopmans 我们不可能知道,因此真正询问它是没有用的。您不妨直接说它是一种名为 JavaHugo 的 全新 语言,其 indexOf 的工作方式与 Javascripts 不同。那么答案是正确的。
  • @HugoKoopmans JavaScript 实现不是由 MarkLogic 从头开始​​构建的;相反,我们集成了 V8 引擎,它也支持 Node.js 和 Chrome。 @Idos 的答案是正确的——问题是在字符串数组中搜索一个整数。为了证明这一点,将此答案中的代码粘贴到查询控制台中,将 document.write(n) 替换为 n 以返回值,然后运行。
  • 顺便说一句,userRoleIdsArray[7]==3191093315651213021; 返回 true 因为双等号,它执行自动类型转换。使用三等号 (userRoleIdsArray[7]===3191093315651213021;) 运行相同的命令,您将得到 false
【解决方案2】:

不匹配之处在于 ValueIterator.toArray() 返回一个值数组 (Value[])。当您调用 .indexOf 时,您传递的是字符串或 unsignedLong 而不是值。因为类型不匹配, .indexOf() 不报告匹配。

您可以通过遍历循环来解决问题。请注意,我使用 '==' 运算符而不是 '===';需要类型转换。

// get roleIds from sec db for this user
var userRoleIds = xdmp.userRoles('my-user');
// map ValueIterator to array
var userRoleIdsArray = userRoleIds.toArray(); 

var target = 15520654661378671735;
var index = -1;

for (var i in userRoleIdsArray) {
  if (userRoleIdsArray[i] == target) {
    index = i;
  }
}
index

【讨论】:

    猜你喜欢
    • 2021-09-02
    • 2017-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多