Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/361.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 根据另一个ID数组对对象数组进行排序_Javascript_Ramda.js - Fatal编程技术网

Javascript 根据另一个ID数组对对象数组进行排序

Javascript 根据另一个ID数组对对象数组进行排序,javascript,ramda.js,Javascript,Ramda.js,我有两个数组 a = [2,3,1,4] b = [{id: 1}, {id: 2}, {id: 3}, {id: 4}] 如何根据a对b进行排序?我期望的输出是 c = [{id: 2}, {id: 3}, {id: 1}, {id: 4}] 我更喜欢使用Ramda或常规JS。您可以根据a创建c,而不必使用b: var a = [2,3,1,4]; var c = []; for(var i = 0; i < a.length; i++){ c.append({id:a[

我有两个数组

a = [2,3,1,4]
b = [{id: 1}, {id: 2}, {id: 3}, {id: 4}]
如何根据
a
b
进行排序?我期望的输出是

c = [{id: 2}, {id: 3}, {id: 1}, {id: 4}]

我更喜欢使用Ramda或常规JS。

您可以根据
a
创建
c
,而不必使用
b

var a = [2,3,1,4];
var c = [];

for(var i = 0; i < a.length; i++){

    c.append({id:a[i]);

}
var a=[2,3,1,4];
var c=[];
对于(变量i=0;i
希望这有帮助!

此解决方案使用辅助对象
c
作为索引

{
    "1": 2,
    "2": 0,
    "3": 1,
    "4": 3
}
var a=[2,3,1,4],
b=[{id:1},{id:2},{id:3},{id:4}],
c=a.reduce(函数(r,a,i){
r[a]=i;
返回r;
}, {});
b、 排序(函数(x,y){
返回c[x.id]-c[y.id];
});
document.write(''+JSON.stringify(b,0,4)+'');
或者更简单一些

var sortOrder = [2,3,1,4],
    items     = [{id: 1}, {id: 2}, {id: 3}, {id: 4}];

items.sort(function (a, b) {
  return sortOrder.indexOf(a.id) - sortOrder.indexOf(b.id);
});

纯javascript,使用数组的一些方法(
ES2015
标准)

var a=[2,3,1,4];
var b=[{id:1},{id:2},{id:3},{id:4}];
var c=[];
a、 forEach(el=>c.push(b.find(e=>e.id==el));

document.write(JSON.stringify(c,0,2));
您可以为JavaScript的方法提供自定义比较函数

使用自定义比较功能确保排序顺序:

let sortOrder = [2,3,1,4],
    items     = [{id: 1}, {id: 2}, {id: 3}, {id: 4}];

const itemPositions = {};
for (const [index, id] of sortOrder.entries()) {
  itemPositions[id] = index;
}

items.sort((a, b) => itemPositions[a.id] - itemPositions[b.id]);
:

  • 如果compareFunction(a,b)返回的值小于0,则将a排序为低于b的索引(即a排在第一位)
  • 如果compareFunction(a,b)返回0,则a和b彼此保持不变,但根据所有不同的元素进行排序。注意:ECMAscript标准不保证这种行为,因此,并非所有浏览器(例如,至少可追溯到2003年的Mozilla版本)都遵守这一点
  • 如果compareFunction(a,b)返回的值大于0,则将b排序到低于a的索引(即b排在第一位)

Hitmands对上述解决方案做出了非常公正的评论:

这种方法是O(n2),在大的列表中会导致性能问题。最好先构建字典,使其保持O(n)

因此,上述解决方案可能不会像您在大输入上所需要的那样快

执行Hitmands的建议:

var a = [2,3,1,4];
var b =  [{id: 1}, {id: 2}, {id: 3}, {id: 4}]
R.find( R.propEq('id', a[0]), b )
R.values(R.mapObjIndexed(  (num, key, obj) => R.find( R.propEq('id', a[key]), b ) , b))

使用Ramda,您必须通过mapObjIndexed函数将b中的对象映射到它们的索引,然后搜索a中的值。您可以尝试一下

对于这些类型的问题真的很有帮助

如果数据的大小很小,我们可以使用一个简单的函数和助手

这对于小型(ish)数据集很有效,但对于大型数据集,通过缩减每次迭代的操作都是低效的

我们可以通过从另一方面解决这个问题来解决这个问题,让我们使用根据对象id对对象进行分组,从而创建字典查找(更好!)。然后我们可以简单地遍历所需的索引,并将它们转换到该位置对应的对象

以下是使用这种方法的解决方案:

R.sortBy(R.pipe(R.prop('id'), R.indexOf(R.__, a)))(b);
// [ { id: 2 }, { id: 3 }, { id: 1 }, { id: 4 } ]
最后,这是另一个非常简洁的解决方案:

const sortBy = (array, values, key = 'id') => ((map) => values.reduce((a,i) => 
a.push(map[i]) && a,[]))(array.reduce((a,i) => (a[i[key]] = i) && a, {}));

我喜欢你用行为组合函数,并将算法与它所使用的数据分离的方式。你得到的代码可读性强,易于维护。

非常好的解决方案。只需保留在这里以备将来使用:)

用法


这里有一个使用Ramda的替代构造,它可能更简洁一些,并且这些函数很容易用于其他用途

const{indexBy,prop,map,flip}=R
常数a=[2,3,1,4]
常数b=[{id:1},{id:2},{id:3},{id:4}]
const toIndexById=indexBy(prop('id'))
常量findIndexIn=翻转(道具)
常数c=map(findIndexIn(toindexbyd(b)),a)
控制台日志(c)
我将对的解决方案进行迭代

这里正确的方法是翻转问题,而不是 “根据
b
给出的顺序排序
a
”, 我宁愿“用来自
a
的数据丰富
b

这使您可以将此函数的时间复杂度保持在
O(n)
, 而不是将其提升到
O(n2)

const pickById=R.pipe(
R.indexBy(R.prop('id')),
右翻转(右支撑),
);
const exprich=R.useWith(R.map,[pickById,R.identity]);
// =====
常量数据=[2,3,1,4];
const source=[{id:1},{id:2},{id:3},{id:4}];
console.log(
丰富(来源、数据),
);
使用ES6映射并查找


真正的
b
对象是否包含除
id
之外的任何内容?可能的重复可以使
sortInsert
成为一个纯函数吗?:)我不认为Ramda在这里很出色tbh,我认为这些解决方案的可读性不如纯JS替代方案……可能不完全是问题所要求的,但仍然是一个有用的人目的跳出框框思考此方法是
O(n2)
,在大列表中会导致性能问题。最好先构建字典,使其保持
O(n)
var groupById = R.groupBy(R.prop('id'), b);

var sort = R.map(function (id) {
    return groupById[id][0];
});

sort(a);
// [ { id: 2 }, { id: 3 }, { id: 1 }, { id: 4 } ]
R.sortBy(R.pipe(R.prop('id'), R.indexOf(R.__, a)))(b);
// [ { id: 2 }, { id: 3 }, { id: 1 }, { id: 4 } ]
const sortBy = (array, values, key = 'id') => ((map) => values.reduce((a,i) => 
a.push(map[i]) && a,[]))(array.reduce((a,i) => (a[i[key]] = i) && a, {}));
a = [2,3,1,4]
b = [{id: 1}, {id: 2}, {id: 3}, {id: 4}]

sortBy(b, a) // [{id: 2}, {id: 3}, {id: 1}, {id:` 4}]
const a = [2,3,1,4];
const b = [{id: 1}, {id: 2}, {id: 3}, {id: 4}];

// map over a, find it in b and return    
const c = a.map((i) => b.find((j) => j.id === i));