从数组中提取对象,如果有预定义键

从数组中提取对象,如果有预定义键

问题描述:

我有一系列对象 - employeesArray,一个对象表示雇员。假定一个对象具有以下结构:从数组中提取对象,如果有预定义键

{ 
    "name": "blabla", 
    "id": 1, 
    "position": { 
     "code": "codeId", 
     "positionString": "CEO" 
    } 
} 

我有对象的另一个数组 - positionsArray,一个对象表示的位置。假设一个对象还具有以下结构:

{ 
    "code": "codeId", 
    "positionString": "CEO" 
} 

假设employeesArray拥有100名员工和positionsArray有15个位置。我想将positionsArray中存在的职位提取到另一个阵列中。

employee.position.codeemployee.position.positionString必须存在于positionsArray

如何实现这一目标?

+0

请添加更多的数据和它的想要的结果。 –

+2

最有效的方法是创建一个来自您想用作查找的数组的位置的哈希表对象。这样你只能迭代每个数组一次 – charlietfl

+1

请显示你的尝试。 *既不是免费的代码编写服务,也不是*“如何”*教程服务 – charlietfl

你可以使用组如果发生在positionsArray代码或位置串有一个有效的方法来检查:

function findEmployees(employeesArray, positionsArray) { 
 
    const codes = new Set(positionsArray.map(({code}) => code)), 
 
      positionStrings = new Set(positionsArray.map(({positionString}) => positionString)); 
 
    return employeesArray.filter(({position: {code, positionString}}) => 
 
     codes.has(code) || positionStrings.has(positionString) 
 
    ); 
 
} 
 

 
// Sample data 
 
var employeesArray = [{ 
 
    "name": "John", 
 
    "id": 1, 
 
    "position": { 
 
     "code": "unknown", 
 
     "positionString": "CEO" 
 
    } 
 
}, { 
 
    "name": "Helen", 
 
    "id": 2, 
 
    "position": { 
 
     "code": "9999", 
 
     "positionString": "Deputy" 
 
    } 
 
}, { 
 
    "name": "Joy", 
 
    "id": 3, 
 
    "position": { 
 
     "code": "9876", 
 
     "positionString": null 
 
    } 
 
}, { 
 
    "name": "Vicky", 
 
    "id": 4, 
 
    "position": { 
 
     "code": "8888", 
 
     "positionString": "Director General" 
 
    } 
 
}, { 
 
    "name": "Jack", 
 
    "id": 5, 
 
    "position": { 
 
     "code": "0001", 
 
     "positionString": "Clerk" 
 
    } 
 
}]; 
 

 
var positionsArray = [{ 
 
    "code": "0123", 
 
    "positionString": "CEO" 
 
}, { 
 
    "code": "9876", 
 
    "positionString": "Director" 
 
}, { 
 
    "code": "5555", 
 
    "positionString": "Head of Unit" 
 
}]; 
 

 
console.log(findEmployees(employeesArray, positionsArray));
.as-console-wrapper { max-height: 100% !important; top: 0; }

+0

我会试试这个。它不应该是“最有效的”,实际上我需要解决方案,不管它有多高效。 – basic

第1步:做一个循环为positionArray每个元素 第2步:在循环体内部,使用过滤器命令过滤对象 第3步:将过滤的员工放入另一个数组中。

var result = []; 
for (var i = 0; i < positionArray.length; i++) { 
    var filteredEmployees = employeesArray.filter(function(emp){ 
     return emp.code == positionArray.code; 
    }); 

    //Now put filtered employees into new array 
    for (var t = 0; t < filteredEmployees.length; t++) { 
     result.push(filteredEmployees[t]); 
    }  
} 

Array.reduce一个也有手头一个很好的工具...的解决方案则可能看起来像......

// Sample data 
 
var employeesArray = [{ 
 
    "name": "John", 
 
    "id": 1, 
 
    "position": { 
 
    "code": "unknown", 
 
    "positionString": "CEO" 
 
    } 
 
}, { 
 
    "name": "Helen", 
 
    "id": 2, 
 
    "position": { 
 
    "code": "9999", 
 
    "positionString": "Deputy" 
 
    } 
 
}, { 
 
    "name": "Joy", 
 
    "id": 3, 
 
    "position": { 
 
    "code": "9876", 
 
    "positionString": null 
 
    } 
 
}, { 
 
    "name": "Vicky", 
 
    "id": 4, 
 
    "position": { 
 
    "code": "8888", 
 
    "positionString": "Director General" 
 
    } 
 
}, { 
 
    "name": "Jack", 
 
    "id": 5, 
 
    "position": { 
 
    "code": "0001", 
 
    "positionString": "Clerk" 
 
    } 
 
}]; 
 

 
var positionsArray = [{ 
 
    "code": "0123", 
 
    "positionString": "CEO" 
 
}, { 
 
    "code": "9876", 
 
    "positionString": "Director" 
 
}, { 
 
    "code": "5555", 
 
    "positionString": "Head of Unit" 
 
}]; 
 

 
var result = employeesArray.reduce(function (collector, employee) { 
 
    if (collector.positions.some(collector.doesMatchBoundEmployee, employee)) { 
 
    collector.employees.push(employee); 
 
    } 
 
    return collector; 
 
}, { 
 

 
    doesMatchBoundEmployee: function (position) { 
 
    return (
 
     (position.code === this.position.code) 
 
     || (position.positionString === this.position.positionString) 
 
    ); 
 
    }, 
 
    positions: positionsArray, 
 
    employees: [] 
 

 
}).employees; 
 

 
console.log("result : ", result);
.as-console-wrapper { max-height: 100%!important; top: 0; }

这里是另一种解决方案,在功能款式:

// Sample data 
const employeesArray = [ 
    { "name": "John", "id": 1, "position": { "code": "unknown", "positionString": "CEO" } }, 
    { "name": "Helen", "id": 2, "position": { "code": "9999", "positionString": "Manager" } }, 
    { "name": "Joy","id": 3, "position": { "code": "9876", "positionString": "Manager" } }, 
    { "name": "Vicky", "id": 4, "position": { "code": "8888", "positionString": "Director" } }, 
    { "name": "Jack", "id": 5, "position": { "code": "0001", "positionString": "Manager" } } 
] 

const positionsArray = [ 
    { "code": "0123", "positionString": "CEO" }, 
    { "code": "9876", "positionString": "Director" }, 
    { "code": "5555", "positionString": "Manager" } 
] 

// we are going to step through the positions array 
// and examine positionsArray.positionString 
// and produce an object that has one property for each position 
const extractPositions = positionsArray.reduce((all, position) => { 
    // set the position to a variable 
    const title = position.positionString 
    // now we are going to filter out every user that has the title 
    // and set the result of that to the title property on the object we are creating 
    all[title] = employeesArray.filter((e) => e.position.positionString === title) 
    // return all is needed because we are accumulating the results 
    return all 
}, {}) // {} is where we define we are creating an object, 
     // and 'return all' adds to it every iteration 

console.log('CEO', extractPositions.CEO) 
console.log('Director', extractPositions.Director) 
console.log('Manager', extractPositions.Manager) 

以下是它的外观变成了一个功能,你可以通过在两个数组拨打:

const sortPositions = (positions, employees) => { 
    const final = positions.reduce((all, position) => { 
    const title = position.positionString 
    all[title] = employees.filter((e) => e.position.positionString === title) 
    return all 
    }, {}) 
    return final 
} 

console.log(sortPositions(positionsArray, employeesArray)) 

而且,这里是非常难以理解没有理由,最大的浓缩版:

const getEmployees = (positions, employees) => 
    positions.reduce((all, position) => { 
    all[position.positionString] = employees.filter((e) => 
     e.position.positionString === position.positionString) 
    return all 
    }, {}) 

console.log(getEmployees(positionsArray, employeesArray)) 

我会选择第二个我因为第三个例子的3个例子,虽然更浓缩会导致你从现在起6个月后回到代码中讨厌生活。第二个不使用implicit returns,它也更明确地帮助理解title的人在逻辑内部很重要。

我们在这里做的基础是有两个数组,我们需要以某种方式将它们与eachother比较,所以在我的例子中,我们决定使用positions数组作为字典,并且创建一个员工列表在词典中找到每个标题。

如果员工没有字典中没有标题或标题,他们将被忽略。

如果有标题有0名员工,则会在最终结果中添加一个空数组。

如果我们想要捕获unsorted员工,这将变得更加复杂,但为此,您可能希望在您的函数中保存雇员数组的副本,并删除每个员工。新数组中剩余的员工将被添加到最终结果中的未排序数组中。这将通过reduce函数的最后一遍完成。就解释而言这不是微不足道的,但它只会增加大约5-10行代码。

下面是一个如何减少工作的例子,因为我认为这是一个非常有用的工具。它是一个累加器,所以它就像一个迭代器(forEach,map),但它允许您随时累积结果,因此您可以构建一个和,数组或对象。

const numbers = [1, 3, 5, 7, 9] 

const addNumbers = numbers.reduce((all, item, i) => { 
    console.log('\nAll is currently:', all) 
    console.log('We are currently looking at:', item) 
    console.log('Current index position:', i) 
    all = all + item 
    return all 
}, 0) 

console.log('\nThe total is:', addNumbers) 

看那0那里}, 0)。如果将其更改为[]{},则可以构建一个数组或对象,而不是总和。如果你制作它[],你可以在内部减少:all.push('anything'),如果你制作它{},你可以做all.prop = 'anything'(或者我们做了all[title],它使用括号表示创建动态属性名称)。

它变得insanely强大,因为,而不仅仅是{},你可以做{ good: [], bad: [] }它允许你创建真正复杂的对象。每个循环遍历原始数组中的每个项目,可以说if (something === 'good') all.good.push(item)等,并构建一个具有超级复杂属性的对象,并且您只需要通过原始数组一次