我有一些如下所示的对象:
one {
team: "yes",
school: "yes",
work: "yes"
}
two {
team: "yes",
school: "yes",
work: "yes"
}
three {
team: "no",
school: "no",
work: "yes"
}
four {
team: "yes",
school: "yes",
work: "yes"
}
您可以看到,除三个对象外,所有对象都是相同的。我希望将对象“三个”保存在变量中
var uniqueObject = three;
如何选择与其他对象不同的对象?
答案 0 :(得分:3)
如果将对象放入数组中,则可以使用数组方法来帮助您实现目标。首先,可以将await
与JSON.stringify()
一起使用,以记录在数组中找到的对象数量。然后,您可以将reduce
与Object.values
一起使用,以查找发生.find
的对象,这将是您的奇数对象。
请参见以下示例:
1
答案 1 :(得分:1)
首先,我们通过Object.value
函数将对象转换为数组。然后,将包含的对象转换为字符串,以允许通过filter
进行字符串比较。筛选器检查当前条目是否真正唯一。之后,我们parse
将返回的String返回给Object。
截至目前,我们只返回第一个唯一值(以防万一)。但是另一方面,当内部对象具有不同的结构或深层嵌套的结构时,这甚至也可以工作!
let obj = {
one: {
team: "yes",
school: "yes",
work: "yes"
},
two: {
team: "yes",
school: "yes",
work: "yes"
},
three: {
team: "no",
school: "no",
work: "yes"
},
four: {
team: "yes",
school: "yes",
work: "yes"
}
};
let res = JSON.parse(Object.values(obj)
.map(o => JSON.stringify(o))
.filter((v,i,arr) => arr.indexOf(v) == arr.lastIndexOf(v))[0] || null);
console.log(res)
答案 2 :(得分:1)
我发现这是一个看似有趣的问题。我的第一种方法类似于Nick Parsons的方法,在结果中添加了JSON.parse
。但是我不喜欢它返回对象的克隆。我的第二次尝试看起来像这样:
const isNotLikeTheOthers = (makeKey) => (objs) =>
objs [Object .entries ( objs.reduce (
(a, obj, idx, __, key = makeKey(obj)) => ({...a, [key] : [...(a[key] || []), idx]}),
{}
)).find (([k, idxs]) => idxs.length == 1)[1][0]]
const oneOfTheseThings = isNotLikeTheOthers (JSON.stringify)
const arr = [{team: "yes", school: "yes", work: "yes"}, {team: "yes", school: "yes", work: "yes"}, {team: "no", school: "no", work: "yes"}, {team: "yes", school: "yes", work: "yes"}];
console .log (
oneOfTheseThings (arr)
)
我写了一个小的变体,以防项目位于对象而不是数组中。
const isNotLikeTheOthers = (makeKey) => (objs, vals = Object .values (objs) ) =>
vals [ Object .entries ( vals .reduce (
(a, obj, idx, __, key = makeKey(obj)) => ({...a, [key] : [...(a[key] || []), idx]}),
{}
)).find (([k, idxs]) => idxs.length == 1)[1][0]]
const oneOfTheseThings = isNotLikeTheOthers (JSON.stringify)
const objs = {one: {team: "yes", school: "yes", work: "yes"}, two: {team: "yes", school: "yes", work: "yes"}, three: {team: "no", school: "no", work: "yes"}, four: {team: "yes", school: "yes", work: "yes"}};
console .log (
oneOfTheseThings (objs)
)
这两个都分开makeKey
,并使用JSON.stringify
。能够提供替代的密钥生成功能可能会很有用。但是在这里内联JSON.stringify
也可能有意义。
请注意,这两个都返回对原始对象的引用,而不是对原始对象的克隆,就像我们可能会进行JSON.stringify
/ JSON.parse
舞蹈一样。尽管我不了解OP的要求,但这似乎很有用。
但是,这种方法存在问题。这是find
操作。一旦知道结果,它应该能够停止。但是我们必须使用这种技术处理每条记录。我们应该能够创建一个一旦知道结果就停止的版本。那是我第三个版本的起源:
const snowflake = (eq) => ([one, two, three, ...rest]) =>
eq(one, two)
? [three, ...rest] .find (x => ! eq (one, x))
: eq (one, three)
? two
: one
const uniqueItem = snowflake (equals)
const arr = [{team: "yes", school: "yes", work: "yes"}, {team: "yes", school: "yes", work: "yes"}, {team: "no", school: "no", work: "yes"}, {team: "yes", school: "yes", work: "yes"}];
console .log (
uniqueItem (arr)
)
<script src="https://bundle.run/ramda@0.26.1"></script>
<script> const {equals} = ramda </script>
在这里,我们编写了一个函数,该函数接受一个测试两个值是否相等的函数,并返回一个基于该函数在数组中查找唯一项的函数。在这种情况下,我使用Ramda的equals
函数进行测试,但是我们可以像使用Underscore或任何本地版本一样容易地进行测试。实际上,我们还可以通过
JSON.stringify
的结果比较
const uniqueItem = snowflake ( (a, b) => JSON.stringify (a) == JSON.stringify (b) )
同样,我们可以内联比较操作,除非我强烈需要更通用的版本,否则我可能会这样做。
此版本似乎是最好的版本。这个问题至少要有三个值才有意义,因此我们将它们命名为one
,two
和three
。我们可以从比较前两个项目开始。如果它们相同,则答案是其余项目中的第一项不等于该第一值。如果它们不同,那么其中一个必须是奇数球,我们可以通过比较第一个和第三个来确定哪个。
此版本的时间效率可能不会比其他版本高,尤其是因为像JSON.stringify
这样的比较必须对我们的基准对象运行多次。我们可以解决这个问题,并将一个参数加入到equals
的某个版本中,但这似乎失去了一些优雅之处。
答案 3 :(得分:0)
您可以使用以下功能对对象进行分组:
function groupObject(object, expression) {
if (typeof expression !== "function") expression = function(x) {
return JSON.stringify(x);
};
return Object.keys(object).reduce(function(result, key) {
var groupKey = expression.call(object, object[key], key, object);
if (!(groupKey in result)) result[groupKey] = {};
result[groupKey][key] = object[key];
return result;
}, {});
}
将获得以下形式的输出:
{
"{\"team\":\"yes\",\"school\":\"yes\",\"work\":\"yes\"}": {
"one": {
"team": "yes",
"school": "yes",
"work": "yes"
},
"two": {
"team": "yes",
"school": "yes",
"work": "yes"
},
"four": {
"team": "yes",
"school": "yes",
"work": "yes"
}
},
"{\"team\":\"no\",\"school\":\"no\",\"work\":\"yes\"}": {
"three": {
"team": "no",
"school": "no",
"work": "yes"
}
}
}
在那之后,您可以找到只有1个项目的组以及该项目的获取名称。
const obj = {
one: {
team: "yes",
school: "yes",
work: "yes"
},
two: {
team: "yes",
school: "yes",
work: "yes"
},
three: {
team: "no",
school: "no",
work: "yes"
},
four: {
team: "yes",
school: "yes",
work: "yes"
}
};
function groupObject(object, expression) {
if (typeof expression !== "function") expression = function(x) {
return JSON.stringify(x);
};
return Object.keys(object).reduce(function(result, key) {
var groupKey = expression.call(object, object[key], key, object);
if (!(groupKey in result)) result[groupKey] = {};
result[groupKey][key] = object[key];
return result;
}, {});
}
var group = groupObject(obj);
var groupItem = Object.values(groupObject(obj)).find(function(group) {
return Object.keys(group).length === 1;
});
var itemName = Object.keys(groupItem)[0];
console.log("Final result: " + itemName);
console.log("Result + object: ");
console.log(groupItem);
console.log("Grouped Object: ");
console.log(group);
为便于记录,上面显示的代码与es-5兼容,并且无需编译器即可在较旧的浏览器中运行。此外,功能groupObject
还可以让您更具体(即groupObject(obj, x => x.team)
仅将team
属性分组):
const obj = {
one: {
team: "yes",
school: "no",
work: "yes"
},
two: {
team: "yes",
school: "no",
work: "yes"
},
three: {
team: "no",
school: "yes",
work: "yes"
},
four: {
team: "yes",
school: "yes",
work: "yes"
}
};
function groupObject(object, expression) {
if (typeof expression !== "function") expression = function(x) {
return JSON.stringify(x);
};
return Object.keys(object).reduce(function(result, key) {
var groupKey = expression.call(object, object[key], key, object);
if (!(groupKey in result)) result[groupKey] = {};
result[groupKey][key] = object[key];
return result;
}, {});
}
// `one` and `two` got matched in the first group although they are not identical to `four`, because only the `team` property is being checked
var group = groupObject(obj, x => x.team);
var groupItem = Object.values(groupObject(obj)).find(function(group) {
return Object.keys(group).length === 1;
});
var itemName = Object.keys(groupItem)[0];
console.log("Final result: " + itemName);
console.log("Result + object: ");
console.log(groupItem);
console.log("Grouped Object: ");
console.log(group);
答案 4 :(得分:0)
这将起作用,希望有帮助。使用Object.values()的简单过滤器,并使用Set带出重复项(以检查其总值是,是还是否)
let js = {
one: {
team: "yes",
school: "yes",
work: "yes"
},
two: {
team: "yes",
school: "yes",
work: "yes"
},
three: {
team: "no",
school: "no",
work: "yes"
},
four: {
team: "yes",
school: "yes",
work: "yes"
}
}
// if array length is 1 there are repeated values ,if its 2 then there are two distinct (yes and no both present)
let res = Object.values(js).filter(ele => {
if ([...new Set(Object.values(ele))].length == 2) {
return ele;
}
})
console.log(res[0])